8

私はすばらしい本を読み進めてきましたが、Applicative Functor には少し苦労しています。

次の例maxでは、2 つの Maybe ファンクターと return の内容に適用されますJust 6

max <$> Just 3 <*> Just 6

以下の例ではLeft "Hello"、Either ファンクターの内容の代わりに が返されるのはなぜLeft "Hello World"ですか?

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

2 に答える 2

13

これは、Functorインスタンス (Applicativeなど) の型パラメーターが 2 番目の型パラメーターであるためです。の

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"

連結を取得します。

于 2012-12-14T12:59:40.497 に答える
10

ダニエルの優れた答えに加えて、私が言いたいことがいくつかあります。

まず、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          -- <<== :( 

第二に、あなたの例は少しトリッキーです。一般に、関数の型とeinEither 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

于 2012-12-14T15:13:44.950 に答える