将 Functor 映射到 Haskell 中的列表

map Functor over a list in Haskell

有点困惑。 fmap 听起来它可以 map 遍及 Maybe 的列表,但如果我使用例如,我无法让它工作fApplyFunctor = (+1) <$> [Just 1, Just 2]

似乎工作得很好的是:map ((+1) <$>) [Just 1, Just 2, Just 3]。从某种意义上说,这似乎有点矫枉过正,我记得 fmap 已经可以自己做到这一点......

No fmap 意味着你可以 map 到任意 Functor 类型(好吧现在把它当作一个集合),但你只能做这 一个 "functor level" 深。如果你 fmap 有一个列表,它完全等同于 map.

然而,

fmap 是在各种 Functor 上定义的,例如列表、Maybe 等。因此您可以在 [=13] 中 fmap =] 映射到 两个 级别:

fApplyFunctor = <b>fmap (fmap (+1))</b> [Just 1, Just 2]

这将导致:

Prelude> fmap (fmap (+1)) [Just 1, Just 2]
[Just 2,Just 3]
Prelude> (fmap (+1)) <$> [Just 1, Just 2]
[Just 2,Just 3]
Prelude> ((+1) <$>) <$> [Just 1, Just 2]
[Just 2,Just 3]

EDIT:像 says, there exists a data type Compose 一样,它在两个(或更多,如果你 级联Functors从而使我们能够 fmap 两层深度。实现方式如下:

newtype Compose f g a = Compose { getCompose :: f (g a) }

instance (Functor f, Functor g) => Functor (Compose f g) where
    fmap f (Compose x) = Compose (fmap (fmap f) x)

所以在这里我们再次在两个级别上执行 fmap

Prelude Data.Functor.Compose> getCompose ((+1) <$> Compose [Just 1, Just 2])
[Just 2,Just 3]

但是如您所见,它需要一些语法来首先将数据包装在 Compose 中,然后 "unwrap" 将其从 Compose 中包装出来,因此这需要一些额外的工作也一样。