【发布时间】:2017-10-09 13:35:42
【问题描述】:
我需要一个这样的函数:
>>> func (+1) [1,2,3]
[[2,2,3],[2,3,3],[2,3,4]]
我的真实案例更复杂,但这个例子显示了问题的要点。主要区别在于,实际上使用索引是不可行的。 List 应该是 Traversable 或 Foldable。
EDIT:这应该是函数的签名:
func :: Traversable t => (a -> a) -> t a -> [t a]
更接近我真正想要的是与traverse 相同的签名,但无法弄清楚我必须使用什么功能才能获得所需的结果。
func :: (Traversable t, Applicative f) :: (a -> f a) -> t a -> f (t a)
【问题讨论】:
-
这在一般情况下是不可能的,因为应用函数的输出不必与输入的类型相同。所以中间结果可能类似于
["Foo", 2, 3]。您应该重新制定您的要求。 -
@EugeneSh。我认为
(+1)函数必须是 endo 是隐含的,否则它是不可能的,正如你所解释的。 -
这是“小丑与小丑”的工作。人们可能会选择更灵活、更准确地说明中间状态。例如,[([],(1,2),[2,3]),([2],(2,3),[3]), ([2,3],(3,4),[ ])],其中状态列表的每个元素都有相应的输入“焦点”元素,我们在左侧看到我们已经拥有的输出,在右侧看到我们尚未访问的输入,以及之前 - and-after 对焦点元素。对于这样的结构,映射函数不必是 endo。
-
@pigworker 这正是我正在寻找的。在继续之前,我还必须对焦点下的元素执行一些带有 副作用 的操作。在一些 Haskell 包中是否有一个很好的“小丑和小丑”实现?
-
我一个都没见过。该论文的文字源代码非常适合谷歌搜索。一些乐于助人的人拿了一份,这里是github.com/mak/course-haskell/blob/master/zipppers/CJ.lhs,这和我找不到我的一样。
标签: haskell traversable