我刚刚阅读了有关circular programmingthis article。对我来说似乎太陌生了。尽管我可以将反馈想象为延迟评估的问题,然后再评估为期望的结果,但是无法将我的头缠住它。因此,我决定编写函数,将函数替换为最小值的列表中的每个元素。

trace :: (a -> c -> (b,c)) -> a -> b
trace f a = b
    where (b,c) = f a c

repminList :: (Num a, Ord a) => [a] -> [a]
repminList = trace repIIminList

repIIminList [x] m = ([m], x)
repIIminList (a:as) m = let (replaced, m) = repIIminList as m
                        in (m : replaced, min a m)

但是repminList [1,2,3]等于[2,3,3]。什么是正确的版本?

最佳答案

您的问题是您有两个不同的m变量,一个阴影在另一个阴影上,因此您最终根本不会使用实际的循环变量。这是repIIminList的固定版本:

repIIminList [x] m = ([m], x)
repIIminList (a:as) m = let (replaced, m') = repIIminList as m
                        in (m : replaced, min a m')

这里m是您作为循环参数收到的列表中的最后一个最小元素。从递归调用m'返回的repIIminList是到目前为止看到的最小值,因此将最终的最小值(即m)附加到结果列表中,然后通过返回min a m'来更新当前的最小值非常重要。

10-04 22:12