作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我对编程和练习编写函数还是个新手,我试图扭转 Prelude drop 的影响;
drop :: Int -> [a] -> [a]
drop 0 [] = []
drop 0 (x:xs) = x:xs
drop n [] = []
drop n (x:xs) = drop (n-1) xs
进入我最初命名为 dropR 的东西。
dropR :: Int -> [a] -> [a] -- drops from the right of the list
dropR 0 [] = []
dropR 0 (x:xs) = x:xs
dropR n [] = []
dropR n (x:xs) = reverse (drop (n-1) (reverse xs ++ [x]))
不幸的是,这没有用,因为输入 dropR 2 [1,2,3,4,5]
返回了 [1,2,3,4]
而不是我希望的 [1,2,3]
。使用 drop 2,我会在列表中得到 3 个值,而不是 4 个。我将函数更改为;
dropR :: Int -> [a] -> [a] -- drops from the right of the list
dropR 0 [] = []
dropR 0 (x:xs) = x:xs
dropR n [] = []
dropR n (x:xs) = reverse (drop n (reverse xs ++ [x]))
它以我想要的方式工作,但我不明白为什么第一个不起作用。我认为它只会反转列表并采用与常规下降相同数量的值,之后我可以反转它。
为什么 drop 需要 drop (n-1)
而我的 dropR 只需要 drop n
?发生这种情况是因为 drop 中的递归而不是 dropR 中的递归吗?
最佳答案
让我们看一个例子:
dropR 2 [1, 2, 3, 4]
在您的第一次尝试中,最后一行匹配,并且在其中:
n = 2
x = 1
xs = [2, 3, 4]
因此:
反转 xs = [4, 3, 2]
反转 xs++ [x] = [4, 3, 2, 1]
drop (n-1) (reverse xs++ [x]) = drop 1 [4, 3, 2, 1] = [3, 2, 1]
reverse (drop (n-1) (reverse xs++ [x])) = [1, 2, 3]
另一方面,在您的第二次尝试中:
反转 xs = [4, 3, 2]
反转 xs++ [x] = [4, 3, 2, 1]
drop n (reverse xs++ [x]) = drop 2 [4, 3, 2, 1] = [2, 1]
reverse (drop (n-1) (reverse xs++ [x])) = [1, 2]
但要深入了解。
观察 reverse xs++ [x]
实际上与 reverse (x:xs)
相同:您正在反转尾部,然后将头贴到它的结束。这与首先反转整个列表是一样的。
所以你真正要做的是:
n
因此,您不妨取消所有现有情况,然后执行以下操作:
dropR n xs = reverse (drop n (reverse xs))
或者更短一点:
dropR n = reverse . drop n . reverse
我认为这个变体稍微好一点,因为它更清楚地表达了这个想法:反转,然后删除 n
,然后再次反转。
关于function - 为什么我的函数 dropR(Prelude drop 的反面)看起来像它的样子?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69292496/
我是一名优秀的程序员,十分优秀!