[英]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.