左右之间的区别

5
在书籍《Learn You a Haskell for Great Good》的关于函子的章节中,有一个涉及Either的例子,我不太理解:
ghci> fmap (replicate 3) (Right "blah")
Right ["blah","blah","blah"]

ghci> fmap (replicate 3) (Left "foo")
Left "foo"

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

5
如果你想要实现后者的行为,Either是一个双函子 - kqr
1个回答

18
Either中的Left构造函数作为“失败情况”被实现。像其他函子一样,一旦这个失败值进入等式,它就会阻止任何真正的计算发生。因此,当您对 Left "foo" 应用 fmap 时,它立即返回相同的“失败”值。
您可以通过查看Either如何实现fmap来看到这一点:
instance Functor (Either a) where
    fmap f (Right x) = Right (f x)
    fmap f (Left x) = Left x

这里的想法是Left "foo"实际上会更加具有描述性,比如Left "无法计算值"。如果您尝试将其他函数应用于该值,则希望“错误”保持不变地传递。

如果有帮助的话,可以想象一下在某些其他类型上使用fmap时失败情况更为明显的情况,例如:

-- Maybe: failure value is `Nothing`
fmap (replicate 3) (Nothing)

这会产生Nothing,而不是[Nothing, Nothing, Nothing]


5
谢谢你的快速回答!我已经理解了Maybe的行为。对于理解Either对我有所帮助的是提醒自己,不是Either是一个函子,而是Either a是一个函子! - mkrieger1
@mkrieger1 一个简单的助记规则来记住它们的区别:Right 表示正确/成功/"对的",而 Left 则表示"不对",因此是错误/不正确/失败的。 - chi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接