无法将类型'(Integer,[String])'与'[String]'匹配

时间:2015-09-16 21:59:41

标签: haskell

在GHCi中编译:

splitLines:: String -> [[String]]
splitLines splitLinesStr = splitWords (lines splitLinesStr)

splitWords:: [String] -> [[String]]
splitWords splitWordList = tupleNums (map words splitWordList)

tupleNums :: (Enum a, Num a) => [b] -> [(a, b)]
tupleNums tupleNumList = zip [1..] tupleNumList

给出以下错误消息:

Couldn't match type ‘(Integer, [String])’ with ‘[String]’

Expected type: [[String]]

Actual type: [(Integer, [String])]
In the expression: tupleNums (map words splitWordList)
In an equation for ‘splitWords’:
splitWords splitWordList = tupleNums (map words splitWordList)

有人知道如何修复此类错误吗?我是初学者所以指针很有帮助。

1 个答案:

答案 0 :(得分:4)

与大多数类型错误一样,错误可以在调用者被调用者,在这种情况下,我怀疑它与< EM>呼叫者

最可能的解释是,您不必致电tupleNums

splitLines:: String -> [[String]]
splitLines splitLinesStr = splitWords (lines splitLinesStr)

splitWords:: [String] -> [[String]]
splitWords splitWordList = map words splitWordList

这很简单,你不会附加任何&#34;行号&#34; (?)你的话。

另一种可能性是,当您开始添加行号时,您无法更新 splitLinessplitWords的类型:

splitLines:: (Enum a, Num a) => String -> [(a,[String])]
splitLines splitLinesStr = splitWords (lines splitLinesStr)

splitWords:: (Enum a, Num a) => [String] -> [(a,[String])]
splitWords splitWordList = tupleNums (map words splitWordList)

tupleNums :: (Enum a, Num a) => [b] -> [(a, b)]
tupleNums tupleNumList = zip [1..] tupleNumList

修改

如何操纵类型签名?我们只讨论splitWords,因为splitLines的情况是等价的。首先让我们来看看表达式:

tupleNums (map words splitWordList)

类型:

  • splitWordList :: String(输入);
  • words :: String -> [String](图书馆);
  • map :: (a -> b) -> [a] -> [b](图书馆);
  • tupleNums :: (Enum c, Num c) => [d] -> [(c, d)](已定义)。

由于名称冲突,我已将ab tupleNames重命名为cd。现在,Haskell如何解释这些类型?

必须填写a的{​​{1}}和b。现在因为map的第一个参数类型为mapa -> b,这意味着words :: String -> [String]a = String。通过这样做,我们使用的b = [String](可以这么说)折叠为:

map

现在,当我们在map words :: [String] -> [[String]] 上调用此函数时,它会进一步折叠为:

splitWordList

现在,此表达式的结果将是map words splitWordList :: [[String]] s。

的列表列表

Haskell还需要猜测String的类型。由于它具有签名:tupleNums并将(Enum c, Num c) => [d] -> [(c, d)]作为第一个参数,这意味着map words splitWordList :: [[String]](思维d = [String]不是c)。所以这崩溃了:

String

它不能/不应该推理tupleNums (map words splitWordList) :: (Enum c, Num c) => [[String]] -> [(c, String)] ,因为目标是尽可能保持函数的通用性。

  

注意(类型推断):但是请注意,Haskell(大多数情况下)不需要给出类型。它有一个类型推断系统,可以生成最通用的类​​型签名。如果您向编译器提供此文件:

c
     

您可以使用以下命令查询Haskell已解决的类型:

splitLines splitLinesStr = splitWords (lines splitLinesStr)

splitWords splitWordList = tupleNums (map words splitWordList)

tupleNums tupleNumList = zip [1..] tupleNumList
     

如果您所说的从类型角度来看没有任何意义,那么它将无法编译。类型可用于自己跟踪项目。有一些(GHC)语言扩展可以使类型系统无法找到最通用的类​​型或让它陷入无限循环。