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?

+3


source to share


1 answer


* 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.

+11


source







All Articles