当我不熟悉Haskell时,请耐心等待。
我试图写一个输出的函数:
输出中的第一个列表应与输入列表相同。该 输出中的第二个列表应包含来自的每个第二个元素 输入列表等。
示例:func "ABCD" = ["ABCD","BD","C","D"]
我开始编写一个函数来获取列表的每个第n个元素:
everyN n xs = case drop (n-1) xs of
[] -> []
(z:zs) -> z : everyN n zs
现在我知道我只需要一个调用此函数的函数,并在每次调用时递增n
值,但我不能考虑如何编写这样的功能或者表达它的最简洁的方式。如果可能的话,我不想使用显式递归并使用haskell语言函数。
有人能指出我正确的方向吗?
答案 0 :(得分:4)
我知道这有点蹩脚,因为@chi已经给你发表了评论 - 但也许作为奖励,我有一个替代你的everyN
:
everyN :: Int -> [a] -> [a]
everyN n xs = every n xs
where every _ [] = []
every 1 (x:xs) = x : every n xs
every m (_:xs) = every (m-1) xs
seqN :: [a] -> [[a]]
seqN xs = [ everyN n xs | n <- [1..length xs] ]
这是使用地图相同(再次提到@chi):
seqN' :: [a] -> [[a]]
seqN' xs = map (flip everyN xs) [1..length xs]
有人让我解释一下:
首先看地图:map :: (a -> b) -> [a] -> [b]
- 现在显然我们想要适应everyN
而everyN
有两个参数我们肯定想要部分应用它某事。正在更改的参数不是输入列表xs
,而n
- xs
将保持不变。
所以我们肯定要将everyN
部分应用于xs
- 但我们不能,因为这个论点是错误的。
flip
救援:此翻转 everyN
的参数:
flip everyN :: [a] -> Int -> [a]
我们可以将此部分应用于xs
并写入:
flip everyN xs :: Int -> [a]
最后我们可以将map
用于n
(当然1 .. length xs
超过length xs
- 因为如果我们跳转的时间超过{{1}},则无需选择任何内容)如图所示。
如何把这个放入一个我不知道的英语句子中;)