理解正确应用

Understanding Right Apply

对于列表,为什么 right apply (*>) 会重复和附加第二个参数 n 次,其中 n 是第一个参数的长度?

ghci> [1,2,3] *> [4,5]
[4,5,4,5,4,5]

默认情况下,*> 运算符定义为

xs *> ys = id <$ xs <*> ys

默认情况下又转换为

const id <$> xs <*> ys

即用id替换xs的每个元素得到xs',然后计算xs' <*> ys[] 是一个 Monad 实例,其中 (=<<) = concatMapApplicative 的其中一条定律阐明了 ApplicativeMonad 实例之间的关系:

pure = return
fs <*> as = fs `ap` as = fs >>= \f -> as >>= \a -> f a

对于列表,这是

fs <*> as = [f a | f <- fs, a <- as]

所以列表的 *> 最终由 Monad 实例决定。

请注意,还有另一个非常明智的 Applicative 列表实例,可通过 Control.Applicative 中的新类型获得:

newtype ZipList a = ZipList [a]
instance Applicative ZipList where
  pure = repeat
  (<*>) = zipWith ($)