gpt4 book ai didi

haskell - 映射同时显示中间状态

转载 作者:行者123 更新时间:2023-12-04 14:23:43 26 4
gpt4 key购买 nike

我需要一个执行此操作的函数:

>>> func (+1) [1,2,3]
[[2,2,3],[2,3,3],[2,3,4]]

我的真实案例更复杂,但这个例子显示了问题的要点。主要区别在于,实际上使用索引是不可行的。 List应该是 TraversableFoldable .

编辑 :这应该是函数的签名:
func :: Traversable t => (a -> a) -> t a -> [t a]

更接近我真正想要的是与 traverse 相同的签名但无法弄清楚我必须使用的功能才能获得所需的结果。
func :: (Traversable t, Applicative f) :: (a -> f a) -> t a -> f (t a)

最佳答案

看起来@Benjamin Hodgson 误读了您的问题并认为您想要 f应用于每个部分结果中的单个元素。因此,您最终认为他的方法不适用于您的问题,但我认为它确实适用。考虑以下变化:

import Control.Monad.State

indexed :: (Traversable t) => t a -> (t (Int, a), Int)
indexed t = runState (traverse addIndex t) 0
where addIndex x = state (\k -> ((k, x), k+1))

scanMap :: (Traversable t) => (a -> a) -> t a -> [t a]
scanMap f t =
let (ti, n) = indexed (fmap (\x -> (x, f x)) t)
partial i = fmap (\(k, (x, y)) -> if k < i then y else x) ti
in map partial [1..n]

在这里, indexed在状态 monad 中运行以向可遍历对象的元素添加递增索引(并“免费”获取长度,无论这意味着什么):
> indexed ['a','b','c']
([(0,'a'),(1,'b'),(2,'c')],3)

而且,正如 Ben 所指出的,它也可以使用 mapAccumL 来编写。 :
indexed = swap . mapAccumL (\k x -> (k+1, (k, x))) 0

然后, scanMap获取可遍历对象,将其映射到类似的前后对结构,使用 indexed对其进行索引,并应用 partial 的序列函数,其中 partial i为第一个 i 选择“afters”其余的元素和“之前”。
> scanMap (*2) [1,2,3]
[[2,2,3],[2,4,3],[2,4,6]]

至于将其从列表概括为其他内容,我无法弄清楚您要对第二个签名做什么:
func :: (Traversable t, Applicative f) => (a -> f a) -> t a -> f (t a)

因为如果你把它专门用于一个列表,你会得到:
func' :: (Traversable t) => (a -> [a]) -> t a -> [t a]

而且完全不清楚您希望在这里做什么。

关于haskell - 映射同时显示中间状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43900340/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com