我正在学习haskell,我试图编写自己的反向函数而不使用递归。
解决方案就是这个功能:
myreverse = foldl (flip (:)) []
我试图了解评估过程中发生的事情,比如说:
myreverse [1..5]
我无法理解这里有什么翻转。有人可以通过逐步解释来记下这里发生的事情吗?
答案 0 :(得分:6)
翻转很容易:
如果您有一个f :: a -> b -> c
函数,那么flip f
就是一个函数:: b -> a -> c
,因此它会为您提供一个新函数,并且翻转您拥有的参数顺序通过。
(:) :: a -> [a] -> [a]
是这种模式的一个函数,因此flip (:)
现在将是一个函数,它首先采用即将成为尾巴然后是新头并返回一个新列表,其中包含:
(flip (:)) [2..4] 1
= (:) 1 [2..4]
= 1 : [2..4]
= [1,2,3,4]
现在你需要这个,因为foldl
是这样定义的:
foldl :: (b -> a -> b) -> b -> [a] -> b
你看 - 你必须传递的函数将是一个首先获取一个列表然后一个元素并返回一个新列表的函数
现在这将折叠成这样的东西:
myreverse [1..5]
= foldl (flip (:)) [] [1,2,3,4,5]
= foldl (flip (:)) (((flip (:)) [] 1)) [2,3,4,5]
= foldl (flip (:)) (1:[]) [2,3,4,5]
= foldl (flip (:)) (((flip (:)) [1] 2)) [3,4,5]
= foldl (flip (:)) (2:[1]) [3,4,5]
= ...
= [5,4,3,2,1]
答案 1 :(得分:3)
你可以试试ghci flip
做什么:
:t (:)
(:) 1 [2..4]
[1,2,3,4]
:t flip (:)
(flip (:)) [2..4] 1
[1,2,3,4]