这里有一些关于其他人的答案的详细说明。
我们在源码里面Control.Applicative
找到
instance Applicative ((->) a) where -- (a ->) is meant here
pure = const
(<*>) f g x = f x (g x)
liftA3 f a b c = f <$> a <*> b <*> c
在 GHCi 中,我们得到
Prelude Control.Applicative> :t liftA3 (,,)
liftA3 (,,) :: (Applicative f) => f a -> f b -> f c -> f (a, b, c)
因此,使用(t->)
as f
,liftA3 (,,)
就可以了:
liftA3 (,,) ~ (t->a) -> (t->b) -> (t->c) -> (t->(a,b,c))
即,调用liftA3 (,,) f1 f2 f3 t
产生一个三元组(f1 t, f2 t, f3 t)
,给定相同类型输入的三个函数:
Prelude Control.Applicative>
liftA3 (,,) (:[]) (quot 12) (`rem`3) 4
([4],3,1)
那么它是怎样工作的?根据 的定义liftA3
,然后是<*>
,
liftA3 (,,) f g h t = ((((,,) <$> f) <*> g) <*> h) t
= (((,,) <$> f) <*> g) t (h t)
= (((,,) <$> f) t (g t) (h t)
现在,(<$>) = fmap
定义instance Functor ((->) t)
,fmap = (.)
所以我们继续
= (((,,) . f) t (g t) (h t)
= (,,) (f t) (g t) (h t)
= (f t, g t, h t)