在 ghci 中有以下内容:
:m + Control.Monad.Error
let f x = Right x
Left 1.0 >> Right 1 >>= f
给出
Left 1.0
据我了解>>运算符丢弃第一个参数的monadic结果, 但我看到它保存在这里。你能解释一下吗?
http://hackage.haskell.org/package/base-4.10.0.0/docs/src/Data.Either.html#Either
奇怪的是,该链接并未显示Either如何实现Monad类型类的方法。答案 0 :(得分:8)
据我所知[,]
>>
运算符丢弃第一个参数的monadic结果,
不,它确实不。它或多或少看到Left
像Maybe
monad看到Nothing
(主要区别在于Left
也带有值)。因此,它有时用作“高级Maybe
”,例如可以携带错误消息。
(>>) :: Monad m => m a -> m b -> m b
是一个函数, f >> g
相当于f >>= \_ -> g
和f >>= const g
。这是Monad
类型类中的默认实现。
因此取决于(>>=) :: Monad m => m a -> (a -> m b) -> m b
的实施方式。
现在Either
为implemented as:
instance Monad (Either e) where Left l >>= _ = Left l Right r >>= k = k r
这意味着如果左侧有 Left l
,则忽略右侧,如果左侧是Right r
,然后k
应用于Right
构造函数包装的值。
因此,我们可以使用(为了清晰起见添加括号)替换您的查询:
Left 1.0 >> Right 1 >>= f
= (>>) (Left 1.0) (Right 1 >>= f)
-> Left 1.0
从语义上讲,您可以将Either
视为Maybe
的“更高级”版本,其中Left
取代Nothing
。因此,从某个时刻Left x
开始,它就会保持Left x
。无论我们如何约束它。
答案 1 :(得分:2)
请注意,该定义与您放弃序列运算符的左值相矛盾:
instance Monad (Either e) where
Left l >>= _ = Left l
Right r >>= k = k r
事实上,在Left
的情况下,Right
值被丢弃。
点击haddocks中Monad
声明下的Either
个实例,查看可以找到的source。
答案 2 :(得分:2)
"结果"被丢弃的仅指a
值包含在m a
值中(而不是总是字面上),而不是其余值。如果是Either
,则表示Right
的值将被忽略,但不会被忽略Left
或Right
,还是Left
的值{1}}。
如果您将>>=
Either
的定义与>>
的默认定义结合起来,那么您会看到>>
这里有效
Left l >> x = Left l >>= \_ -> x = Left l
Right r >> x = Right r >>= \_ -> x = x
并且第二个子句中的结果确实不依赖于r
。