应用函数和左边的任何一个

时间:2012-12-14 12:53:52

标签: haskell functor either applicative

我一直在阅读great good一书,但我与Applicative Functors稍作讨论。

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

max <$> Just 3 <*> Just 6

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

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

2 个答案:

答案 0 :(得分:12)

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

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"

要连接。

答案 1 :(得分:8)

为了补充Daniel的优秀答案,我想提出几点:

首先,here's应用实例:

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

你可以看到这是'短路' - 一旦它到达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          -- <<== :( 

其次,你的例子有点棘手。通常,函数的类型和e中的Either e无关。这是<*>的类型:

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

如果我们进行替换f - &gt;&gt; Either e,我们得到:

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

尽管在您的示例中,ea匹配,但通常它们不会匹配,这意味着您无法多态实现应用该函数的Either e的Applicative实例一个左手的论点。