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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With