ダニエルの優れた答えに加えて、私が言いたいことがいくつかあります。
まず、Applicative インスタンスは次のとおりです。
instance Applicative (Either e) where
pure = Right
Left e <*> _ = Left e
Right f <*> r = fmap f r
これが「ショートサーキット」であることがわかります。a に到達するとすぐ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
inEither 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
する Applicative インスタンスをポリモーフィックに実装することはできません。Either e