我刚刚阅读了有关circular programming
的this 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'
来更新当前的最小值非常重要。