【问题标题】:Applicative Functors and Left from Either应用函子和左从
【发布时间】:2012-12-14 12:53:52
【问题描述】:

我一直在研究great good 这本书,但我在使用 Applicative Functors 时遇到了一些困难。

在以下示例中,max 应用于两个 Maybe 函子的内容并返回 Just 6

max <$> Just 3 <*> Just 6

为什么在以下示例中返回 Left "Hello" 而不是 Either 函子的内容:Left "Hello World"

(++) <$> Left "Hello" <*> Left " World"

【问题讨论】:

  • 这是 Either 的传统用法,Right 代表您感兴趣的值,而 Left 代表失败。 Right(正确)值可以使用 Applicative 和 Functor 组合和修改,而 Left over bad 值会顽固地持续存在,因此它适用于像简单编译器那样报告第一个错误之类的事情。

标签: haskell functor either applicative


【解决方案1】:

这是因为Functor 实例(以及Applicative 等)中的类型参数是第二个类型参数。在

Either a b

a 类型和 Left 值不受函数或应用操作的影响,因为它们被视为失败案例或无法访问。

instance Functor (Either a) where
    fmap _ (Left x)  = Left x
    fmap f (Right y) = Right (f y)

使用Right

(++)  <$> Right "Hello" <*> Right " World"

获得连接。

【讨论】:

  • 如果要翻转类型变量,可以使用errors 包中的Data.EitherR 模块。这提供了两个选项:flipE,它翻转一个参数 EitherEitherR,它将它包装在一个交换变量顺序的新类型中,给出对称的 FunctorApplicative 实例。
【解决方案2】:

为了补充丹尼尔的出色回答,我想说明几点:

首先,here's Applicative 实例:

instance Applicative (Either e) where
    pure             =  Right
    Left  e  <*>  _  =  Left e
    Right f  <*>  r  =  fmap f r

你可以看到这是“短路”——一旦它碰到Left,它就会中止并返回那个Left。您可以通过穷人的严格分析来检查这一点:

ghci> (++) <$> Left "Hello" <*> undefined 
Left "Hello"                              -- <<== it's not undefined :) !!

ghci>  (++) <$> Right "Hello" <*> undefined 
*** Exception: Prelude.undefined          -- <<== undefined ... :(

ghci> Left "oops" <*> undefined <*> undefined 
Left "oops"                               -- <<== :)

ghci> Right (++) <*> undefined <*> undefined 
*** Exception: Prelude.undefined          -- <<== :( 

其次,你的例子有点棘手。一般来说,函数的类型和Either e中的e是没有关系的。这是&lt;*&gt;s 类型:

(<*>) :: Applicative f => f (a -> b) -> f a -> f b

如果我们替换f -->> Either e,我们得到:

(<*>) :: Either e (a -> b) -> Either e a -> Either e b

尽管在您的示例中,ea 匹配,但通常它们不会匹配,这意味着您不能多态地实现 Either e 的 Applicative 实例,它将函数应用于左侧参数。

【讨论】:

    猜你喜欢
    • 2012-02-24
    • 2011-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多