左右之间的区别

mkr*_*er1 9 haskell

我目前正在阅读优秀的"了解你是一个很好的Haskell",在关于仿函数部分中有一个Either我不明白的例子:

ghci> fmap (replicate 3) (Right "blah")
Right ["blah","blah","blah"]
Run Code Online (Sandbox Code Playgroud)
ghci> fmap (replicate 3) (Left "foo")
Left "foo"
Run Code Online (Sandbox Code Playgroud)

后者为什么不Left ["foo", "foo", "foo"]呢?

Mic*_*eld 14

Left构造上Either被实现为"失败案例".像其他仿函数一样,一旦这个失败值进入等式,它就会阻止任何真实的计算发生.所以,当你申请fmapLeft "foo"它立即返回相同的"失败"值.

您可以通过查看Either实现如何看到这一点fmap:

instance Functor (Either a) where
    fmap f (Right x) = Right (f x)
    fmap f (Left x) = Left x
Run Code Online (Sandbox Code Playgroud)

这里的想法Left "foo"实际上是更具描述性的东西,比如Left "Value could not be computed".如果您尝试将其他函数应用于该值,则只需要将"错误"完整传递.

如果它fmap有所帮助,想象一下如何在故障情况更明显的其他类型上工作,例如:

-- Maybe: failure value is `Nothing`
fmap (replicate 3) (Nothing)
Run Code Online (Sandbox Code Playgroud)

Nothing不会产生[Nothing, Nothing, Nothing]

  • 感谢您及时回复!我已经理解了"可能"的行为.什么帮助我'要么'是提醒自己,不是'要么'是一个算子,而是'要么'! (5认同)
  • @chi ....因此任何Functor/Applicative/Monad实例都可以独自留下. (2认同)