[英]Applicative Functors and Left from Either
我一直在努力通过大良的书,但我与应用型函子稍微挣扎。
在以下示例中,将max
应用于两个Maybe仿函数的内容,并返回Just 6
。
max <$> Just 3 <*> Just 6
在下面的示例中,为什么返回Left "Hello"
而不是Either函数的内容: Left "Hello World"
?
(++) <$> Left "Hello" <*> Left " World"
这是因为Functor
实例(和Applicative
等)中的type参数是第二个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"
获得串联。
除了丹尼尔的出色回答外,我想提出几点要点:
首先, 这是 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 -- <<== :(
其次,您的示例有些棘手。 通常,函数的类型与e
中的Either e
都不相关。 这是<*>
的类型:
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
如果我们进行替换f
->> Either e
,我们得到:
(<*>) :: Either e (a -> b) -> Either e a -> Either e b
尽管在您的示例中, e
和a
匹配项通常不会,但是这意味着您无法为Either e
都多态实现一个Applicative实例,该实例将函数应用于左手参数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.