将Functor映射到Haskell的列表上

时间:2018-11-01 15:22:12

标签: haskell functor map-function

有点困惑。 fmap听起来可以map遍历Maybe的整个列表,但是如果我使用例如fApplyFunctor = (+1) <$> [Just 1, Just 2]

看起来非常正常的是:map ((+1) <$>) [Just 1, Just 2, Just 3]。从某种意义上说,这似乎是过大的,我记得fmap本身已经可以做到这一点...

1 个答案:

答案 0 :(得分:9)

没有fmap意味着您可以映射到任意Functor类型上(现在将其作为一个集合来考虑),但是您只能这样做 “ functor level” 深。如果您用列表fmap,则它完全等效于map

但是

fmap是在各种Functor上定义的,例如列表,Maybe等。在这里,您可以在fmap中使用fmap映射到两个级别:

fApplyFunctor = fmap (fmap (+1)) [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]

编辑:就像@DanielWagner所说的那样,存在一种数据类型Compose,该数据类型可以处理两个(如果是级联,则为更多)Functor深入两个级别。实现方式如下:

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中,因此还需要一些额外的工作。