0

I'm trying to learn Haskell in guidance of Learn You a Haskell, but the following puzzles me.

lucky :: (Integral a) => a -> String
lucky 7 = "LUCKY NUMBER SEVEN!"  
lucky x = "Sorry, you're out of luck, pal!"

As you can see, there's one line up there stating the exact types of the function. But is this necessary? Can't the types of parameters and return values be deduced from the patterns below that line?

Johnson Steward
  • 534
  • 3
  • 16
  • 1
    Related: https://stackoverflow.com/questions/27067905/when-are-type-signatures-necessary-in-haskell – Zeta Jan 20 '16 at 10:36

2 Answers2

6

You are right, they are absolutely not necessary. However, it's a very common practice to state the type of the function nevertheless, for at least two reasons :

  • To tell the compiler what you actually mean. In case you make a mistake writing the function, the compiler will not infer a bad type, but warn you of your mistake
  • To tell the people who read your code. They'll have to find out the type of the function anyway while understanding the code, so you might as well make it easier for them. Having the type explicitly makes the code more readable.

This is why, although they are optional, the types of top level functions are almost always spelled out in Haskell code.


To complete with what Zeta said, it is not necessary in this case. However, in some situations, it is necessary to specify the type of the function when the code is too ambiguous to infer.

madjar
  • 12,691
  • 2
  • 44
  • 52
  • Does that line generate actual code (like some runtime type checking? I'm completely new to Haskell..) – Johnson Steward Jan 20 '16 at 10:34
  • you should read it as a hint to the compiler (which might or might not change the generated code based on those hints) - if you don't give it the compiler will try to infer it – Random Dev Jan 20 '16 at 10:35
  • *"You are right, they are absolutely not necessary."* In ___this___ case. There are several cases where GHC will yell at you if you leave the type signature and spit out several pages of ambiguity errors. – Zeta Jan 20 '16 at 10:39
  • 2
    @JohnsonSteward: Nope! Haskell is statically typed, and all types are resolved at compile time. Whether you tell the compiler what the type is (with a type signature like that), or you let the compiler figure it out for itself (via type inference), the resulting generated code is the same. (One exception: if you give the code a *more specific* type, then the compiler may generate different output.) – Antal Spector-Zabusky Jan 20 '16 at 11:49
  • Read further, and discovered this: `zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]`. Seems like this is not easily deducible for the compiler... – Johnson Steward Jan 20 '16 at 13:11
  • @JohnsonSteward Haskell should be able to infer that type from any of the obvious implementations. Have you *tried* any of this? – Ben Jan 21 '16 at 00:08
  • @Ben for `zipWith'`? I implemented with this: `zipWith` _ [] _ = [] \n`, `zipWith' _ _ [] = [] \n` and `zipWith' f (x:xs) (y:ys) = f x y : zipWith' f xs ys \n` – Johnson Steward Jan 21 '16 at 00:33
  • @JohnsonSteward With your code in a file (nothing else; no type signature), I can load it in ghci, type `:t zipWith'` and it shows `zipWith' :: (t -> t2 -> t1) -> [t] -> [t2] -> [t1]`. Although I did correct that your first equation has `zipWith =` instead of `zipWith' =`; wasn't sure if that was just an issue of display here, given the slightly messed up code formatting. – Ben Jan 21 '16 at 00:44
  • @JohnsonSteward Vanilla Haskell (no extensions) has almost complete type inference (I believe the only exceptions involve type-class-polymorphic code that doesn't actually pin down the particular type). You can often write full programs without *any* type annotations at all (although most Haskellers would choose to add them anyway). – Ben Jan 21 '16 at 00:48
  • @Ben That's a typo, I'm on a phone and mistakenly typed `\`` for `'`. – Johnson Steward Jan 21 '16 at 01:15
-2

For documentation purpose, and because for some type extensions the automatic inference fails. Read here.

optimusfrenk
  • 1,271
  • 2
  • 16
  • 34