Haskell语言学习笔记(5)Applicative

Applicative

class Functor f => Applicative f where
    pure :: a -> f a

    (<*>) :: f (a -> b) -> f a -> f b
    (<*>) = liftA2 id

    liftA2 :: (a -> b -> c) -> f a -> f b -> f c
    liftA2 f x = (<*>) (fmap f x)

    (*>) :: f a -> f b -> f b
    a1 *> a2 = (id <$ a1) <*> a2

    (<*) :: f a -> f b -> f a
    (<*) = liftA2 const
Applicative(应用函子) 是一个类型类。Functor 是 Applicative 的基类。
pure 函数将值放入 Applicative 这个计算环境之中。
<*> (apply)操作符将封装在 Applicative 中的函数应用到封装在 Applicative 中的值之上。
lift2 函数提升一个二元函数,将其应用到两个封装在 Applicative 中的值之上。

Applicative的法则

pure id <*> v = v
pure (.) <*> u <*> v <*> w = u <*> (v <*> w)
pure f <*> pure x = pure (f x)
u <*> pure y = pure ($ y) <*> u

<$>

(<$>) :: Functor f => (a -> b) -> f a -> f b

[] 是 Applicative

instance Applicative [] where
    pure x    = [x]
    -- (<*>) :: [a -> b] -> [a] -> [b]
    fs <*> xs = [f x | f <- fs, x <- xs]
Prelude> [(*0),(+100),(^2)] <*> [1,2,3]  
[0,0,0,101,102,103,1,4,9]
Prelude> (\x y z -> [x,y,z]) <$> (+3) <*> (*2) <*> (/2) $ 5  
[8.0,10.0,2.5]

Maybe 是 Applicative

instance Applicative Maybe where
    pure = Just
    -- (<*>) :: Maybe (a -> b) -> Maybe a -> Maybe b
    Just f  <*> m       = fmap f m
    Nothing <*> _m      = Nothing
Prelude> Just (+2) <*> Just 3
Just 5
Prelude> (+) <$> Just 2 <*> Just 3
Just 5
Prelude> Just (+2) <*> Nothing
Nothing
Prelude> Just 7 <* Just 8
Just 7
Prelude> Just 7 *> Just 8
Just 8
Prelude> liftA2 (:) (Just 3) (Just [4])
Just [3,4]

((->) r) 是 Applicative

instance Applicative ((->) a) where
    pure = const
    (<*>) f g x = f x (g x)
Prelude> (+) <$> (+2) <*> (*3) $ 4
18
(+) <$> (+2) <*> (*3) $ 4 = (4+2)+(4*3) = 18

ZipList 是 Applicative

newtype ZipList a = ZipList { getZipList :: [a] }
instance Applicative ZipList where  
    pure x = ZipList (repeat x)  
    ZipList fs <*> ZipList xs = ZipList (zipWith (\f x -> f x) fs xs)  
Prelude Control.Applicative> getZipList $ (+) <$> ZipList [1,2,3] <*> ZipList [100,100,100]
[101,102,103]

(<**>), liftA, liftA3

(<**>) :: Applicative f => f a -> f (a -> b) -> f b
(<**>) = liftA2 (\a f -> f a)
liftA :: Applicative f => (a -> b) -> f a -> f b
liftA f a = pure f <*> a
liftA3 :: Applicative f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d
liftA3 f a b c = liftA2 f a b <*> c
Prelude Control.Applicative> Just 2 <**> Just (*3)
Just 6
Prelude Control.Applicative> liftA (+2) (Just 3)
Just 5
Prelude Control.Applicative> liftA3 (,,) (Just 3) (Just 4) (Just 5)
Just (3,4,5)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值