Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between these two function type definitions?

Tags:

haskell

For the following trivial function definitions:

printLength1::(Num a)=>String->a
printLength1 s = length s


printLength2::String->Int
printLength2 s = length s

Why are they not the same ? In what situations i should choose one over the other?

And i get this error for printLength1:

Couldn't match type `a' with `Int'
      `a' is a rigid type variable bound by
          the type signature for rpnc :: String -> a at test.hs:20:1
    In the return type of a call of `length'
    In the expression: length s
    In an equation for `rpnc': rpnc s = length s

I understand this error. But how can i fix this ? I've already read some posts here about rigid type variable but still couldn't understand how to fix it.

like image 428
McBear Holden Avatar asked Nov 30 '11 00:11

McBear Holden


People also ask

What are the different types of functions explain?

1. Injective (One-to-One) Functions: A function in which one element of Domain Set is connected to one element of Co-Domain Set. 2. Surjective (Onto) Functions: A function in which every element of Co-Domain Set has one pre-image.


2 Answers

The first type signature is more general. It means the result can be any Num--it is polymorphic on its return type. So the result of your first function could be used as an Int or an Integer or any other Num instance.

The problem is that length returns an Int rather than any Num instance. You can fix this using fromIntegral:

printLength1 :: Num a => String -> a
printLength1 s = fromIntegral $ length s

Note that the signature of fromIntegral . length (which is the point-free version of the code above) is Num c => [a] -> c. This matches the signature you specified for your printLength1 function.

like image 187
Tikhon Jelvis Avatar answered Sep 23 '22 06:09

Tikhon Jelvis


Quoting LearnYouAHaskell.com:

Note: This function has a type of numLongChains :: Int because length returns an Int instead of a Num a for historical reasons. If we wanted to return a more general Num a, we could have used fromIntegral on the resulting length.

like image 35
Vincent Savard Avatar answered Sep 26 '22 06:09

Vincent Savard