class (Functorf) => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b
Applicative 中定义了 pure 和 <*>
Applicative Functor 的几个实例
Maybe
1 2 3 4
instanceApplicativeMaybewhere pure = Just Nothing <*> _ = Nothing (Just f) <*> something = fmap f something
Applicative 相较于 Functor 的改进之处:
with the Applicative type class, we can chain the use of the <*> function, thus enabling us to seamlessly operate on several applicative values instead of just one. For instance, check this out:
1
pure(+) <*> Just3 <*> Just5-- Just 8
lift 相当于 pure
Applicative 中还定义了 <$>
<$> 相当于中缀版的 fmap,但应用于 Applicative 的链式调用特别方便
1 2 3
(<$>) :: (Functor f) => (a -> b) -> f a -> f b f <$> x = fmap f x -- pure f <*> x <*> y <*> ... === fmap f x <*> y... === f <$> x <*> y...
List 也是 Applicative Functor
1 2 3
instanceApplicative [] where pure x = [x] fs <*> xs = [f x | f <- fs, x <- xs]
理解了 haskell 中 List 的 <*> 也就理解了 Ramda 中的 liftN
将 fs 中的每个 f map 到 xs 中的每个 x。
pure id <*> v = v -- Identity pure f <*> pure x = pure (f x) -- Homomorphism u <*> pure y = pure ($ y) <*> u -- Interchange pure (.) <*> u <*> v <*> w = u <*> (v <*> w) -- Composition