Jim*_*ies 7 haskell functor either applicative
我一直在阅读这本伟大的好书,但我正在与Applicative Functors稍作讨论.
在下面的示例max中应用了两个Maybe functor的内容并返回Just 6.
max <$> Just 3 <*> Just 6
Run Code Online (Sandbox Code Playgroud)
为什么在以下示例中Left "Hello"返回而不是Either仿函数的内容:Left "Hello World"?
(++) <$> Left "Hello" <*> Left " World"
Run Code Online (Sandbox Code Playgroud)
Dan*_*her 12
这是因为Functor实例中的类型参数(Applicative等等)是第二个类型参数.在
Either a b
Run Code Online (Sandbox Code Playgroud)
在a类型和Left值不受函子或应用性的操作,因为它们被认为是失败的案例或以其他方式不可访问.
instance Functor (Either a) where
fmap _ (Left x) = Left x
fmap f (Right y) = Right (f y)
Run Code Online (Sandbox Code Playgroud)
用Right,
(++) <$> Right "Hello" <*> Right " World"
Run Code Online (Sandbox Code Playgroud)
得到串联.
为了增加Daniel的优秀答案,我想提出几点:
首先,这是 Applicative实例:
instance Applicative (Either e) where
pure = Right
Left e <*> _ = Left e
Right f <*> r = fmap f r
Run Code Online (Sandbox Code Playgroud)
你可以看到这是"短路" - 一旦它命中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 -- <<== :(
Run Code Online (Sandbox Code Playgroud)
其次,你的例子有点棘手.通常,函数的类型和ein Either e是无关的.这<*>是类型:
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
Run Code Online (Sandbox Code Playgroud)
如果我们进行替换f- >> Either e,我们得到:
(<*>) :: Either e (a -> b) -> Either e a -> Either e b
Run Code Online (Sandbox Code Playgroud)
虽然在你的例子e和a匹配中,通常它们不会,这意味着你不能多态地实现一个Applicative实例,Either e它将函数应用于左侧参数.