问题
I'm trying to learn about Monads in Haskell. Given the data type:
data XY a = X a | Y a
I would like 'X a >>= f'
to return 'f a'
and 'Y a >>= f'
to just ignore 'f'
and return 'Y a'
.
This is the code I wrote:
4 instance Monad XY where
5 return x = X x
6 (X a) >>= f = f a
7 (Y a) >>= f = Y a
and this is the compiler error I got:
prog.hs:7:25:
Couldn't match expected type `b' with actual type `a'
`b' is a rigid type variable bound by
the type signature for >>= :: XY a -> (a -> XY b) -> XY b
at prog.hs:6:9
`a' is a rigid type variable bound by
the type signature for >>= :: XY a -> (a -> XY b) -> XY b
at prog.hs:6:9
In the first argument of `Y', namely `a'
In the expression: Y a
In an equation for `>>=': (Y a) >>= f = Y a
Failed, modules loaded: none.
Could you help me understandiq what I am missing?
回答1:
Consider the type of >>=
:
(>>=) :: XY a -> (a -> XY b) -> XY b
With your case for Y a >>= f
, you're returning an XY a
, not an XY b
. That's why the type error is telling you it can't match an expected b
with the actual a
.
In general what you're trying to do (always return Y a
) doesn't make sense because XY
only has one type parameter that you can't change without also changing the value Y a
. Have a look at the Monad instance for Either to see how this kind of thing can be done with a slightly different type.
来源:https://stackoverflow.com/questions/24233245/type-error-in-monad-definition