Applicative 处于 FunctorMonad 之间.其定义如下:

1
2
3
4
5
6
class Functor f => Applicative f where
pure :: a -> f a
liftA2 :: (a -> b -> c) -> f a -> f b -> f c
(<*>) :: f (a -> b) -> f a -> f b
(*>) :: f a -> f b -> f b
(<*) :: f a -> f b -> f a

一个新的函数

1
(<*>) :: Applicative f => f (a -> b) -> f a -> f b

一个不太恰当的比喻:

  • Functor 是一个已知的函数应用在一个盒子里的值上(这个盒子可能是空的,即没有值)
  • Applicative 是一个盒子里的函数应用在一个盒子里的值上(这两个盒子可能都没有值,即没有函数或者没有值)

(*>)(<*) 运算符也是比较有用的的,在计算完两边的表达式后,返回右值/左值,可以结合 condition check 使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
decrease :: Int -> Maybe Int
decrease i = if i>0 then Just (i-1) else Nothing

small :: Int -> Maybe Int
small i = if i<10 then Just i else Nothing

decreaseSmall :: Int -> Maybe Int
-- do what decrease does, but fail if small fails
decreaseSmall i = decrease i <* small i

-- ===== Evaluation Result =====
decreaseSmall 4 ==> Just 3
decreaseSmall 0 ==> Nothing
decreaseSmall 11 ==> Nothing

traverse 是 Applicative 版本的 mapM

Alternative Applicative

1
2
<|> :: f a -> f a -> f a
-- 如果左边可选,那么就选左边;否则选右边