无法匹配预期的类型错误

时间:2014-05-15 11:49:36

标签: haskell

作为初学者,我正在研究Haskell 99问题的第3项。第一个代码片段是我的解决方案。但是,我无法添加[a] -> Int -> a的类型声明。

它产生错误:Couldn't match type 'a' with 'Int'

--My Solution
--elementAt :: [a] -> Int -> a
elementAt xs num = head . reverse $ takeWhile (<num+1) xs

同时,问题3中的一个解决方案与相同的输出完美配合。

elementAt' :: [a] -> Int -> a
elementAt' list i = list !! (i - 1)

我在没有声明的情况下使用GHCI中的:type作为elementAt并显示:

elementAt :: (Num c, Ord c) => [c] -> c -> c

这两个功能有什么区别?

2 个答案:

答案 0 :(得分:3)

takeWhile (<num+1) xs表示您希望在列表xs前面加上元素,而元素(不是索引!)小于num + 1 。由于您将num(这是一个Int)与列表元素进行比较,编译器会推断列表元素也必须是Int,这与您的类型声明相矛盾。

如果没有类型声明,GHC会推断xs的元素和num必须是相同的类型(因为您将列表元素与num进行比较)。此类型必须具有Ord实例(用于比较)以及Num实例(因为添加)。

答案 1 :(得分:1)

takeWhile (< num + 1)的类型为[Int] -> [Int]

xs的类型为[a]

基本上,您尝试将谓词Int -> Bool应用于a类型的元素。

如果要根据列表中的位置进行过滤,首先需要使用每个元素的位置来扩充输入列表。您可以使用zip

轻松完成此操作
zip xs [1..]

然后,您可以根据结果列表的第二个元素的值删除元素。