Applicative functors

2415 ワード

何だ?
class (Functor f) => Applicative f where  
    pure :: a -> f a  
    () :: f (a -> b) -> f a -> f b  

maybe
instance Applicative Maybe where  
    pure = Just  
    Nothing  _ = Nothing  
    (Just f)  something = fmap f something  
ghci> pure (+)  Just 3  Just 5  
Just 8  
ghci> pure (+)  Just 3  Nothing  
Nothing  
ghci> pure (+)  Nothing  Just 5  
Nothing  

一般的な関数をapplicative functorに適用できます.少し書くだけで関数をアプリケーションスタイルに変えることができ、アプリケーションtivesを操作してアプリケーションtivesに返信することができます.
List
instance Applicative [] where  
    pure x = [x]  
    fs  xs = [f x | f 
ghci> [(*0),(+100),(^2)]  [1,2,3]  
[0,0,0,101,102,103,1,4,9]  

ghci> [(+),(*)]  [1,2]  [3,4]  
[4,5,5,6,3,4,6,8]  

ghci> (++)  ["ha","heh","hmm"]  ["?","!","."]  
["ha?","ha!","ha.","heh?","heh!","heh.","hmm?","hmm!","hmm."] 

ghci> [ x*y | x  (*)  [2,5,10]  [8,10,11]  
[16,20,22,40,50,55,80,100,110]  

ghci> filter (>50) $ (*)  [2,5,10]  [8,10,11]  
[55,80,100,110]  


IO
instance Applicative IO where  
    pure = return  
    a  b = do  
        f 
myAction :: IO String  
myAction = do  
    a  getLine  getLine  

main = do  
    a  getLine  getLine  
    putStrLn $ "The two lines concatenated turn out to be: " ++ a  

関数#カンスウ#
instance Applicative ((->) r) where  
    pure x = (\_ -> x)  
    f  g = \x -> f x (g x)  
ghci> :t (+)  (+3)  (*100)  
(+)  (+3)  (*100) :: (Num a) => a -> a  
ghci> (+)  (+3)  (*100) $ 5  
508 

2つのアプリケーションtive functorを<>に与えると、新しいアプリケーションtive functorを生成することができるので、彼に2つの関数を捨てると、新しい関数を得ることができます.だからどうしたの?私たちが(+)(+3)<>(100)をすると、私たちは実際に関数を作っています.彼は(+3)と(100)の結果を+に適用します.実際の例を見ると、(+)(+3)<>(100)$5が最初に5が(+3)と(*100)に捨てられ、8と500が生成されるのを見ることができます.そして+は8と500にセットされ、508を得る.
ghci> (\x y z -> [x,y,z])  (+3)  (*2)  (/2) $ 5  
[8.0,10.0,2.5]  

ZipList
instance Applicative ZipList where  
        pure x = ZipList (repeat x)  
        ZipList fs  ZipList xs = ZipList (zipWith (\f x -> f x) fs xs)