In Haskell I can define a function like this:
foo :: Int -> Int
foo n = n + 1
If I want to be anal, I can add a type signature to the last line like this:
foo :: Int -> Int
foo n = n + 1 :: Int
I can also define a function bar
in terms of a type class like this:
class Rel a b where
aToB :: a -> b
bar :: (Rel a b) => a -> b
bar a = aToB a
However if I add a type signature to the implementation of bar
(a benign change, or so I thought), I get a compile error.
bar :: (Rel a b) => a -> b
bar a = aToB a :: b
And here's the error:
Could not deduce (Rel a b1) arising from a use of `aToB'
from the context (Rel a b)
bound by the type signature for bar :: Rel a b => a -> b
at q.hs:79:1-23
Possible fix:
add (Rel a b1) to the context of
an expression type signature: b1
or the type signature for bar :: Rel a b => a -> b
In the expression: aToB val :: b
In an equation for `bar': bar val = aToB val :: b
I think the error means that the compiler isn't convinced that the b
in the implementation of bar
is the same as the b
in the type signature of bar
. However, I'm not sure why that would be the case.
Why do I get this compile error when I add a type signature to my function implementation?
You actually need a language extension and a bit of extra syntax to make the two b
type variables be the same:
{-# LANGUAGE ScopedTypeVariables #-}
bar :: forall a b . (Rel a b) => a -> b
bar a = aToB a :: b
The forall
is essentially saying "a
and b
should be in scope for the whole definition", and ScopedTypeVariables
is needed to be allowed to use this syntax.
I guess this is really a historic wart in the design of the language.
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