将Functor映射到Haskell中的列表上



有点混乱。fmap听起来可以在Maybe的列表中使用map,但如果我使用例如fApplyFunctor = (+1) <$> [Just 1, Just 2],则无法使其工作。

看起来非常好用的是:map ((+1) <$>) [Just 1, Just 2, Just 3]。这似乎有些过头了,因为我记得fmap已经可以自己做到了。。。

没有fmap意味着您可以在任意Functor类型上映射(我们现在将其视为一个集合(,但您只能在一个"函子级别">深度上执行此操作。如果您使用列表fmap,则它与map完全等效。

然而,fmap是在所有类型的Functors上定义的,如列表、Maybes等。因此,在这里,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]

EDIT:正如@DanielWagner所说,存在一种数据类型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中,然后再将其从Compose中"展开",因此这也需要一些额外的工作。

相关内容

  • 没有找到相关文章

最新更新