开发者

`Ord a =>` or `Num a =>`

开发者 https://www.devze.com 2023-03-12 13:56 出处:网络
I have the following functions: which (x:xs) = worker x xs worker x [] = x worker x (y:ys) x > y= worker y ys

I have the following functions:

which (x:xs) = worker x xs
worker x [] = x
worker x (y:ys)
    | x > y      = worker y ys
    | otherwise  = worker x ys

and am wondering how I should define the types signatures of these above functions which and worker?

For Example, which of the following ways would be best as a type signature for worker?

worker :: Num a => a -> [a] -> a,

or

worker :: Ord a => a -> [a] -> a?

I'm just really confused and don't get whi开发者_开发知识库ch these three I should choose. I'd appreciate your thoughts. Thanks.


If you define the function without an explicit type signature, Haskell will infer the most general one. If you’re unsure, this is the easiest way to figure out how your definition will be read; you can then copy it into your source code. A common mistake is incorrectly typing a function and then getting a confusing type error somewhere else.

Anyway, you can get info on the Num class by typing :i Num into ghci, or by reading the documentation. The Num class gives you +, *, -, negate, abs, signum, fromInteger, as well as every function of Eq and Show. Notice that < and > aren’t there! Requiring values of Num and attempting to compare them will in fact produce a type error — not every kind of number can be compared.

So it should be Ord a => ..., as Num a => ... would produce a type error if you tried it.


If you think about what your functions do, you'll see that which xs returns the minimum value in xs. What can have a minimum value? A list of something Orderable!


Ask ghci and see what it says. I just copy-pasted your code as is into a file and loaded it into ghci. Then I used :t which is a special ghci command to determine the type of something.

ghci> :t which
which :: (Ord t) => [t] -> t
ghci> :t worker
worker :: (Ord a) => a -> [a] -> a

Haskell's type inference is pretty smart in most cases; learn to trust it. Other answers sufficiently cover why Ord should be used in this case; I just wanted to make sure ghci was clearly mentioned as a technique for determining the type of something.


I would always go with the Ord type constraint. It is the most general, so it can be reused more often.

There is no advantage to using Num over Ord.

Int may have a small advantage as it is not polymorphic and would not require a dictionary lookup. I would stil use Ord and use the specialize pragma if I needed to for performance.


Edit: Altered my answer after comments.

It depends on what you want to being able to compare. If you want to being able to compare Double, Float, Int, Integer and Char then use Ord. If you only want to being able to compare Int then just use Int.

If you have another problem like this, just look at the instances of the type class to tell which types you want to be able to use in the function.

  • Ord documentation
0

精彩评论

暂无评论...
验证码 换一张
取 消