美文网首页
Applicative functors

Applicative functors

作者: mxxxxx | 来源:发表于2017-04-23 21:41 被阅读0次
    是什么
    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 上。只要稍微写一些 <$> 跟 <*> 就可以把函数变成 applicative style,可以操作 applicatives 并回传 applicatives。

    List

    instance Applicative [] where  
        pure x = [x]  
        fs <*> xs = [f x | f <- fs, x <- xs]  
    
    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], y <- [8,10,11]]     
    [16,20,22,40,50,55,80,100,110]     
    
    ghci> (*) <$> [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 <- a  
            x <- b  
            return (f x)  
    
    myAction :: IO String  
    myAction = do  
        a <- getLine  
        b <- getLine  
        return $ a ++ b  
    
    myAction :: IO String  
    myAction = (++) <$> 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 
    

    将两个 applicative functor 喂给 <> 可以产生一个新的 applicative functor,所以如果我们丢给他两个函数,我们能得到一个新的函数。所以是怎么一回事呢?当我们做 (+) <$> (+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)  
    

    相关文章

      网友评论

          本文标题:Applicative functors

          本文链接:https://www.haomeiwen.com/subject/bpayzttx.html