了解在列表中插入元素时的错误

时间:2015-04-15 03:58:47

标签: haskell

所以我现在正在学习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]"

3 个答案:

答案 0 :(得分:7)

你的问题是(正如Silvio已经告诉你的那样):的用法,但让我们分析一下这些类型,看看错误的来源以及你自己如何看待错误:

让我们检查类型

看看

(take k l : x) ++ drop k l

(++)的类型为[a] -> [a] -> [a],因此take k l : xdrop 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 : []。在最后一种情况下,我们使用(:)提取列表的头部。