【问题标题】:couldn't match type 'a' with 'String'无法将类型“a”与“字符串”匹配
【发布时间】:2016-03-30 11:02:37
【问题描述】:

我在 haskell 中做某种编译器,我遇到了这个问题:

这是我目前的代码:

data Command a = Input a | Print a

readCommand:: Read a => String -> Command a
readCommand entrada
    | tokens!!0 == "INPUT" = Input (tokens!!1)
    | tokens!!0 == "PRINT" = Print (tokens!!1)
    where
        tokens = words entrada
        listInstr = lines entrada

但我收到此错误:

无法将类型 'a' 与 'String' 匹配; 'a' 是一个严格的类型变量,由 readC:: Read a => String -> Command a 的类型签名绑定

预期类型:[a];实际类型:[String]

这个错误是否意味着如果我在函数上声明我有一个字符串,类型'a'也不能是一个字符串?

感谢您的帮助

【问题讨论】:

  • 我猜你在哪里寻找 ...= Input (read $ tokens!!1) ...这将尝试 read 输入字符串中的单词/标记到你的类型 a
  • 顺便说一句:也许你应该从一个应该首先处理不同类型的标记(数据类型)的解析器开始?
  • PS 这意味着你承诺返回一个a,但后来只产生了一个String - 所以如果我说readCommand "INPUT 12" :: Command Int,你应该会看到问题
  • 感谢您的回答,是的,我有许多其他数据类型,我只是不想发布有关我的问题的不必要信息

标签: haskell


【解决方案1】:

这个错误意味着如果你承诺一个Command a作为结果,你必须产生一个你的函数调用者请求的Command a类型的结果(只要它满足条件Read a)。因此,您的类型签名允许编译以下代码:

x :: Integer
x = readCommand ""

y :: String
y = readCommand ""

z :: [Double]
z = readCommand ""

根据您的类型签名,readCommand 的所有这些用法都是有效的,因此 readCommand 需要能够生成任何这些类型的值。按照您定义它的方式,无论请求哪种类型,它都将始终生成 Command String。由于这不是您在类型中所承诺的,因此您会收到编译错误。

如果你想生成Command Strings 作为结果,你需要你的类型是readCommand :: String -> Command String。如果您希望您的类型成为现在的样子,您需要实际生成所请求类型的值。

请注意,您需要Read a,但从不实际使用read 函数,这就是需要Read a 的关键。

【讨论】:

  • 好的,知道了,感谢您的帮助,现在我明白了问题所在。谢谢!
  • 有没有办法让haskell推断字符串的类型?我的意思是,对于这种情况很容易,因为我可以简单地更改数据类型并使其期望一个字符串(因为无论如何它都会是变量),但是你将如何使它成为通用的?例如:如果 tokens!!1 是 5,让 haskell 得到 5 作为 int 而不是 String
  • @Outer2g 只需使用read,其类型为Read a => String -> a
  • 对不起,我的坚持,但是,你如何使用阅读?它编译但是,当我用字符串执行它时:“INPUT X”:输入***异常:Prelude.read::no parse。我知道当使用 ghci 和使用 read 时,你必须像这样转换它:read "X"::String,但我不知道如何在代码中使用它。感谢您的宝贵时间
  • @Outer2g read "X" :: String 不是演员表,它只是告诉read 当上下文不清楚时你想要哪种类型。如果在需要字符串的上下文中使用它,则不需要类型注释。无论如何,问题不在于 GHC 无法确定类型(如果是,你会得到一个编译错误告诉你),而是 X 不是 String 的有效输入。如果您在 GHCi 中尝试 read "X" :: String,您会看到同样的异常。 Stringread 实例需要一个 Haskell 样式的字符串,包括双引号。所以它需要是INPUT "X"INPUT X。 ...
猜你喜欢
  • 2018-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多