这个基于 foldl 的函数是如何工作的:"myreverse = foldl (flip (:)) []"?
How does this foldl-based function work: "myreverse = foldl (flip (:)) []"?
我正在学习 haskell,我尝试在不使用递归的情况下编写自己的反向函数。
解决方法是这个函数:
myreverse = foldl (flip (:)) []
我想了解在评估过程中发生了什么,比如:
myreverse [1..5]
我不明白 flip 在这里做什么。有人可以逐步解释这里发生的事情吗?
翻转相当容易:
如果你有一个函数 f :: a -> b -> c
那么 flip f
是一个函数 :: b -> a -> c
所以它给你一个新的函数并且 翻转 您必须传递的参数顺序。
(:) :: a -> [a] -> [a]
是此模式的一个函数,因此 flip (:)
现在将是一个函数,它首先采用 soon-to-be 尾部,然后是新的头部和 returns 你一个包含这些的新列表:
(flip (:)) [2..4] 1
= (:) 1 [2..4]
= 1 : [2..4]
= [1,2,3,4]
现在你需要这个,因为 foldl
是这样定义的:
foldl :: (b -> a -> b) -> b -> [a] -> b
你看 - 你必须传递的函数将首先接受一个列表,然后是一个元素和 returns 一个新列表
这现在将全部折叠成这样的东西:
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]
您可以在 ghci 中尝试 flip
的作用:
:t (:)
(:) 1 [2..4]
[1,2,3,4]
:t flip (:)
(flip (:)) [2..4] 1
[1,2,3,4]
我正在学习 haskell,我尝试在不使用递归的情况下编写自己的反向函数。
解决方法是这个函数:
myreverse = foldl (flip (:)) []
我想了解在评估过程中发生了什么,比如:
myreverse [1..5]
我不明白 flip 在这里做什么。有人可以逐步解释这里发生的事情吗?
翻转相当容易:
如果你有一个函数 f :: a -> b -> c
那么 flip f
是一个函数 :: b -> a -> c
所以它给你一个新的函数并且 翻转 您必须传递的参数顺序。
(:) :: a -> [a] -> [a]
是此模式的一个函数,因此 flip (:)
现在将是一个函数,它首先采用 soon-to-be 尾部,然后是新的头部和 returns 你一个包含这些的新列表:
(flip (:)) [2..4] 1
= (:) 1 [2..4]
= 1 : [2..4]
= [1,2,3,4]
现在你需要这个,因为 foldl
是这样定义的:
foldl :: (b -> a -> b) -> b -> [a] -> b
你看 - 你必须传递的函数将首先接受一个列表,然后是一个元素和 returns 一个新列表
这现在将全部折叠成这样的东西:
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]
您可以在 ghci 中尝试 flip
的作用:
:t (:)
(:) 1 [2..4]
[1,2,3,4]
:t flip (:)
(flip (:)) [2..4] 1
[1,2,3,4]