【发布时间】:2019-11-16 14:34:17
【问题描述】:
我们知道,fmap 的签名是(a -> b) -> f a -> f b,其中f 是Functor。
为了尽可能通用,更好地分解代码,人们可能希望将“事物列表”映射到另一个可能不同的“事物列表”,这似乎很自然。凭直觉,我不明白为什么它不可行或不可取。
我正在寻找的是一个函数gmap,其行为与fmap 相同,但具有gmap :: (a -> b) -> (f a) -> (g b) 的签名,我允许到达和离开容器不同。
我不确定这在f 和g 是Functors 的一般情况下是否有意义,但是“事物列表”的概念听起来更本质上是由Traversable 类捕获的,假设我最感兴趣的是迭代数据。
所以也许签名应该是gmap :: (Traversable f, Traversable g) => (a -> b) -> (f a) -> (g b)。
即使g 与f 的性质不同,它仍然是可以从左到右遍历的东西,所以仍然感觉应该能够将f 的第k 个访问元素映射到g 的第 k 个访问元素。
假设我的思路没有出错,Haskell中有这样的功能吗?
本质上,我的问题是,您如何在 Haskell 中以最简洁和优雅的方式将一个类似列表的东西转换为另一个?
【问题讨论】:
-
如何将列表变成树?两者都是可遍历的。即使一棵树可以从左到右遍历,知道它的遍历也不允许以独特的方式重建树。我们可以生成“一棵树”,但这需要一个非常随意的选择。像 foldable/traversable 这样的类本质上描述了消费容器的方式,而不是生产容器。也许你想要另一个课程。
-
@chi 是的,它可能不是正确的类,那么我会为此目的寻找最通用的类。
-
假设存在这样一个类,它是否只支持类似列表的容器?你能想象任何其他可以从列表中以有意义的方式创建的容器吗?
-
我不确定,但这看起来不像
fmap的组合和函子之间的自然转换..? -
Yeah I thought of natural transformations, somehow what I want is mapping a functor to another functor..- 虽然我对 Haskell 中的自然变换不是很熟悉,但在数学中(“从函子到另一个函子的映射”)准确地是什么一个自然的转变是。