我想复制列表的第 n 个元素,而我对 haskell 的了解非常有限。 我尝试将列表分成两部分,然后获取第一部分的最后一个元素并将其粘贴到这些部分之间:
dupl n (x:xs) = (take n (x:xs)) ++ ( (x:xs) !! n) ++ (drop n (x:xs))
但我总是得到错误:
Prelude> :l f.hs
[1 of 1] Compiling Main ( f.hs, interpreted )
f.hs:5:39:
Occurs check: cannot construct the infinite type: a0 = [a0]
In the first argument of `(:)', namely `x'
In the first argument of `(!!)', namely `(x : xs)'
In the first argument of `(++)', namely `((x : xs) !! n)'
Failed, modules loaded: none.
谁能告诉我我做错了什么?
最佳答案
列表! n
返回列表元素,而不是列表。 ++
只能连接列表;您不能使用 ++
将列表元素添加到列表中。
更正式地说,!!
有一个类型:
(!!) :: [a] -> Int -> a
这意味着它接受一个 a
列表和一个 Int
,并返回一个 a
。另一方面,++
具有以下类型:
(++) :: [a] -> [a] -> [a]
这意味着它接受两个 a
列表并返回一个新的 a
列表。所以你可以看到 ++
接受列表,但是 !!
不返回列表,所以你不能像那样将它们链接在一起。
我们如何解决这个问题?你需要把元素 list !! n
到一个列表中,以便将它连接到其他两个列表,而类型检查器不会发出嘶嘶声。
这应该可以解决问题:
dupl n l = (take n l) ++ [l !! n] ++ (drop n l)
等效地,将所选元素添加到右侧列表,并将其连接到原始列表的另一半:
dupl n l = (take n l) ++ ((l !! n):(drop n l))
读者注意:与@Marimuthu 的建议不同,如果 n
是越界索引,上述两个函数都会引发异常。异常来自 !!
。
关于list - Haskell 在某个位置重复元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15078441/