How to read compiler error
I wrote a Monad implementation for a custom type:
data Sum a b =
First a
| Second b
deriving (Eq, Show)
instance Functor (Sum a) where
fmap _ (First x) = First x
fmap f (Second y) = Second (f y)
instance Applicative (Sum a) where
pure = Second
First x <*> _ = First x
_ <*> First x = First x
Second f <*> Second x = Second (f x)
instance Monad (Sum a) where
return = pure
(First a) >>= _ = First a
(Second a) >>= k = Second (k a)
and I know this is wrong. The compiler complains:
D:\haskell\chapter18\src\SumMonad.hs:39:24: error:
* Couldn't match type `b' with `Sum a b'
`b' is a rigid type variable bound by
the type signature for:
(>>=) :: forall a1 b. Sum a a1 -> (a1 -> Sum a b) -> Sum a b
at D:\haskell\chapter18\src\SumMonad.hs:38:15
Expected type: Sum a b
Actual type: Sum a (Sum a b)
* In the expression: Second (k a)
In an equation for `>>=': (Second a) >>= k = Second (k a)
In the instance declaration for `Monad (Sum a)'
* Relevant bindings include
k :: a1 -> Sum a b
(bound at D:\haskell\chapter18\src\SumMonad.hs:39:20)
(>>=) :: Sum a a1 -> (a1 -> Sum a b) -> Sum a b
(bound at D:\haskell\chapter18\src\SumMonad.hs:38:5)
Failed, modules loaded: none.
How do I read the compiler error?
source to share
* Couldn't match type `b' with `Sum a b'
Translation: I (the compiler) expected a b
and got it instead Sum a b
.
`b' is a rigid type variable bound by
the type signature for:
(>>=) :: forall a1 b. Sum a a1 -> (a1 -> Sum a b) -> Sum a b
Translation: because of the signature, the >>=
specific value of the type of the type variable b
cannot be chosen by you, but by your caller. You can't just pass me some value and expect to b
take the type of your expression as its type value (remember, it b
's a type variable).
Expected type: Sum a b
Actual type: Sum a (Sum a b)
Translation: To make it easier for you, I give you a little more context. I expected Sum a b
and you passed it on to me Sum a (Sum a b)
. You can already see that the problem is in bold here
(>>=) :: forall a1 b. Sum a a1 -> (a1 -> Sum a b) -> Sum a b
because that is the type of values that your implementation of this function should take.
* In the expression: Second (k a)
In an equation for `>>=': (Second a) >>= k = Second (k a)
In the instance declaration for `Monad (Sum a)'
More context for you. I (the compiler) don't like the expression
Second (k a)
in the equation
(Second a) >>= k = Second (k a)
here you can infer what the Second (k a)
type is Sum a (Sum a b)
instead of Sum a b
.
And even more helpful posts for you:
* Relevant bindings include
k :: a1 -> Sum a b
(bound at D:\haskell\chapter18\src\SumMonad.hs:39:20)
(>>=) :: Sum a a1 -> (a1 -> Sum a b) -> Sum a b
(bound at D:\haskell\chapter18\src\SumMonad.hs:38:5)
Translation: the result is k a
already there Sum a b
, you see? So if you think of my previous ones (hopefully helpful posts), it Second (k a)
will be of a type Sum a (Sum a b)
that is not Sum a b
, as I told you before.
source to share