所以我现在正在学习haskell,而且我无法理解我在以下函数中做错了什么,该函数在索引{{1}处插入元素x
在列表k
1。l
2。insertElem x k l = take k l ++ (x : drop k l)
现在,我知道正确的答案是1号,但我不明白为什么2号号码对于insertElem x k l = (take k l : x) ++ drop k l
来说是错误的。
错误是"无法构造无限类型:a~ [a]。预期类型:[[a]],实际类型:[a]"
答案 0 :(得分:7)
你的问题是(正如Silvio已经告诉你的那样):
的用法,但让我们分析一下这些类型,看看错误的来源以及你自己如何看待错误:
看看
(take k l : x) ++ drop k l
(++)
的类型为[a] -> [a] -> [a]
,因此take k l : x
和drop k l
部分都必须是相同类型的列表。
查看drop
您获得Int -> [a] -> [a]
所以您现在知道:
k
的类型为Int
l
的类型为[a]
[a]
take k l : x
也需要输入[a]
现在看(:)
它的类型为a -> [a] -> [a]
,所以为了解决这个问题,现在需要x
让类型[a]
和take k l
具有类型a
。
take
的类型为Int -> [a] -> [a]
,我们已经知道l
的类型为[a]
,因此您可以获得:
take k l
的类型为[a]
(:)
)take k l
类型a
因此,您需要a
同时以某种方式成为[a]
,a ~ [a]
意味着错误所在。
答案 1 :(得分:4)
:
操作将一个元素(第一个参数)添加到列表(第二个参数)。因此,它期望第一个参数是一个元素,第二个参数是一个列表,而不是相反。如果你想这样做,你会这样做:
insertElem x k l = take k l ++ [x] ++ drop k l
答案 2 :(得分:1)
insertElem
的递归定义,用于说明(:)
,
insertElem :: a -> Int -> [a] -> [a]
insertElem e 0 xs = e : xs
insertElem e k [] = [e] -- k > length xs
insertElem e k (x:xs) = x : insertElem e (k-1) xs
这里insertElem
提供了一个a
列表,我们在其中附加要插入的实际元素的else列表的当前头部。
将a
类型的元素附加到a
列表使用(:)
。请注意,在第二种情况下,我们将一个元素e
附加到一个空列表,即[e]
;这相当于e : []
。在最后一种情况下,我们使用(:)
提取列表的头部。