我正在努力了解Haskell中的Monads。 鉴于数据类型:
data XY a = X a | Y a
我希望'X a >>= f'
返回'f a'
和'Y a >>= f'
,忽略'f'
并返回'Y a'
。
这是我写的代码:
4 instance Monad XY where
5 return x = X x
6 (X a) >>= f = f a
7 (Y a) >>= f = Y a
这是我得到的编译器错误:
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.
你能帮我理解我错过的东西吗?
答案 0 :(得分:9)
考虑>>=
的类型:
(>>=) :: XY a -> (a -> XY b) -> XY b
根据Y a >>= f
的个案,您将返回XY a
,而不是XY b
。这就是为什么类型错误告诉您它无法与预期的b
与实际a
匹配。
一般来说,您尝试做的事情(始终返回Y a
)没有意义,因为XY
只有一个类型参数,如果不更改值{{}},则无法更改1}}。看看Monad
instance for Either
,看看如何通过稍微不同的类型来完成这种事情。