我有一个函数f :: (a -> a) -> a -> ((a -> a), a)
。 (在特定情况下,a
为Int
,但这无关紧要。)
我有一个函数initial :: a -> a
和一个输入列表(inputs :: [a]
)。
我需要将f
应用于inputs
的所有元素,但是,对于每个元素,我需要获取上一次迭代的输出的fst
部分并将其作为下一个输入的(a -> a)
部分。作为输出,我需要一个类型[a]
的列表,它是每次迭代输出的snd
部分。
我如何递归地将f
应用于输出的fst
部分和inputs
的元素,同时构建一个中间snd
部分的列表输出
答案 0 :(得分:3)
您可能会喜欢mapM
。下面我给它它的类型,该类型的特殊化,特殊类型的newtype展开,以及进一步的专业化。最终的类型对你来说应该很熟悉。我使用~::
非正式地表示"大约有类型"。
mapM :: Monad m => (a -> m b) -> [a] -> m [b]
mapM :: (a -> State s b) -> [a] -> State s [b]
mapM ~:: (a -> s -> (s, b)) -> [a] -> s -> (s, [b])
mapM ~:: (a -> (a -> a) -> (a -> a, a)) -> [a] -> (a -> a) -> (a -> a, [a])
最后一个类型准确描述了您想要做的事情:它可以(略微修改)f
,inputs
和initial
作为参数,并生成输出列表(以及一些辅助信息)。
答案 1 :(得分:0)
听起来像scanl
可能会有所帮助:
scanl g (initial, undefined) xs
where g (i,_) a = f i a
要从结果列表中删除初始元素(始终比输入列表长1),请对结果应用tail
。