Pal*_*Pal 5 haskell list replicate
我仍然是Haskell的初学者.我尝试做一些模式匹配.我想重复列表中的每个元素n次.N由列表中每个元素的索引位置确定.比如['1', '2', '3']应该给我:['1', '2', '2', '3', '3', '3'].这是一个练习,我不应该使用prebuild-list-functions.
我试过这样的事情:
test [] = []
test (first:[]) = [first]
test (first:second:rest) = first : second : test (second:rest)
Run Code Online (Sandbox Code Playgroud)
但它只是在第一个元素后加倍了每个元素.我想到elemIndex并复制但我不应该使用这些功能.我的想法是使用elemIndex并使用它作为我的"n"并使用复制或类似之后的"n"和递归.在模式匹配中我需要类似的东西.但我想,我觉得太复杂了.有没有人有想法?
Haskell的一个重要部分是将问题分解为更小的问题.所以让我们打破你的问题吧.
你需要做的一件事就是重复一个元素.正如您已经发现的,此功能以Haskell的形式存在于replicate函数中.但你可以轻松地自己实现它.
repeatNTimes :: Int -> a -> [a]
repeatNTimes 0 _ = []
repeatNTimes n x = x : repeatNTimes (n - 1) x
Run Code Online (Sandbox Code Playgroud)
如果我们重复零次,请返回空列表.否则,将元素放在前面并递归.
现在我们可以重复一些事情 让我们编写一个跟踪列表位置的函数.它看起来像这样.
testImpl :: Int -> [a] -> [a]
Run Code Online (Sandbox Code Playgroud)
它将获取一个整数(当前位置)和列表的尾部,并返回给定该列表的特定部分的结果.和以前一样,我们有两种情况:一种是列表为空,另一种是不是.第一种情况很简单; 如果列表为空,则返回空列表.如果列表非空,请重复第一个元素,然后递归.
testImpl :: Int -> [a] -> [a]
testImpl _ [] = []
testImpl n (x:xs) = repeatNTimes n x ++ testImpl (n + 1) xs
Run Code Online (Sandbox Code Playgroud)
++是一个内置函数,它连接两个列表.如果你真的想要,你也可以自己实现.现在,首先,我们考虑的第一个元素是元素1,因为我们要重复一次,因此我们将通过传递开始递归1来testImpl.
test :: [a] -> [a]
test = testImpl 1
Run Code Online (Sandbox Code Playgroud)
完整的例子:
repeatNTimes :: Int -> a -> [a]
repeatNTimes 0 _ = []
repeatNTimes n x = x : repeatNTimes (n - 1) x
testImpl :: Int -> [a] -> [a]
testImpl _ [] = []
testImpl n (x:xs) = repeatNTimes n x ++ testImpl (n + 1) xs
test :: [a] -> [a]
test = testImpl 1
Run Code Online (Sandbox Code Playgroud)