具有以下功能:
between :: a -> [a] -> [[a]]
between i [] = [[i]]
between i r@(x:xs) = [[i]++r] ++ map f (between i xs)
where f = (\n->[x] ++ n)
between 0 [1,2]
的结果是:
[[0,1,2],[1,0,2],[1,2,0]]
这怎么可能?我能够理解前两种情况:
[0,1,2]
,[[0]++[1,2]]
[1,0,2]
因为map f [[0]++[2]]
(其中x是1) 地图是否也在递归?并保留对所有初始x
的引用,以便它只是联系所有人?在我的脑海中,最终结果将是:
[[0,1,2],[1,0,2],[2,0]]
PS:“地图递归”也是一个很长的路线:
\n -> [1] + n
\n ->[2] + n
\n ->[3] + n
\n ->[m] + n
答案 0 :(得分:2)
首先,让我们修复此函数以使用cons(:
)而不是++
,因为前者在将元素添加到前面时更有效且惯用列表,它还可以简化相当多的功能:
between i [] = [[i]]
between i r@(x:xs) = (i : r) : map (x:) (between i xs)
这将更容易用于完成这些步骤:
between 0 [1, 2] =
(0 : [1, 2]) : map (1:) (between 0 [2])
[0, 1, 2] : map (1:) ((0 : [2]) : map (2:) (between 0 []))
[0, 1, 2] : map (1:) ([0, 2] : map (2:) [[0]])
[0, 1, 2] : map (1:) ([0, 2] : [[2, 0]])
[0, 1, 2] : map (1:) [[0, 2], [2, 0]]
[0, 1, 2] : [1:[0, 2], 1:[2, 0]]
[0, 1, 2] : [[1, 0, 2], [1, 2, 0]]
[[0, 1, 2], [1, 0, 2], [1, 2, 0]]
因此,通过等式推理,我们可以计算出GHC为达到这个答案所采取的步骤。
答案 1 :(得分:1)
但请记住,之间返回整个尾部的结果
between 0 [2]
给出
[[0, 2], [2, 0]]
将f
预先1
应用于所有内容
[[1, 0, 2], [1, 2, 0]]
最后,我们添加[[i]++r]
(最好写成[i:r]
)
[[0, 1, 2], [1, 0, 2], [1, 2, 0]]