List Haskell在特定位置重复元素

List Haskell在特定位置重复元素,list,haskell,list-comprehension,List,Haskell,List Comprehension,我想复制列表的第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: Occu

我想复制列表的第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] -> [a] -> [a]
这意味着它接受
a
s和
Int
的列表,并返回
a
<另一方面,代码>++
具有以下类型:

(!!) :: [a] -> Int -> a
(++) :: [a] -> [a] -> [a]
这意味着它接受两个
a
s列表,并返回一个新的
a
s列表。所以你可以看到
++
接受列表,但是
不返回列表,因此不允许将它们像那样链接在一起


我们如何解决这个问题?您需要将元素
放入列表!!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
是越界索引,上述两个函数都会引发异常。异常来自

您还可以使用:


如果
n
超出范围,则此项不会中断。

如果选择了错误的索引,请注意清空,但是-

dupN n xs = let (first, x:rest) = splitAt (n-1) xs in first ++ x:x:rest

这是最漂亮的。我想在first++[x,x]++rest中使用
会更好。谢谢!我也很喜欢你的建议。