【问题标题】:Haskell - couldn't match expected type with actual typeHaskell - 无法将预期类型与实际类型匹配
【发布时间】:2016-07-18 23:20:10
【问题描述】:

在这段代码中没有办法做到多态:

data NumericExpr e = Var e | Const e | Times [e] | Div e e deriving (Show,Read)

readCommand:: a -> b
readCommand entrada = Var 3

它给了我一个无法复制的大错误:

无法将预期类型 b 与实际类型匹配 NumericExpr e0 b 是 由 readcommand :: a 的类型签名绑定的刚性类型变量 -> b


编辑:

尚未使用:

data NumericExpr e = Var e | Const e | Plus [e] | Minus [e] | Times [e] | Div e e deriving (Show,Read)
data Expr e = Num e | String e

readCommand:: Expr b => a -> b
readCommand entrada = Var 3

【问题讨论】:

标签: haskell compilation


【解决方案1】:

您是说readCommand 可以产生用户请求的任何类型b 的结果,但您产生的结果Var 3NumericExpr e(对于某些数字类型e)。所以实际上你只能产生NumericExpr e类型的结果,而不是任何类型的结果。所以你的类型签名不正确。如果您想决定 3 的特定类型,它需要是 readCommand :: Num b => a -> NumericExpr b 或只是 readCommand :: a -> NumericExpr Integer

请注意,没有可能产生结果的a -> b 类型的函数(对b 没有任何约束)。那就是该类型的任何可能的函数都将永远循环或崩溃。

【讨论】:

  • 问题是返回不会总是一个 numericExpr 但它也可能是 booleanExpr (这是字符串)
  • @DanielRocaLopez 然后你需要一个类型data Expr = Num NumericExpr | Bool BolleanExpr。或者更好的是,首先不要有单独的数字和布尔表达式类型。
  • 我为什么不应该把它们分开?虽然你最后的评论对我有帮助,但我会试试的
  • @DanielRocaLopez 因为通常它导致的问题多于解决的问题。例如:您的 NumericExpr 类型有一个 case Var 用于变量。大概BooleanExpr 也需要一个变量案例,对吧?所以我们称之为BoolVar。现在你的解析器看到了一个变量名。它应该产生Var 还是BoolVar?除非您通过解析器携带变量的类型信息,否则此时您无法真正知道。这通常不是您需要或不想在解析器中跟踪的信息,它使您的代码比需要的更痛苦。
  • @DanielRocaLopez Expr 不是类型类,它必须是 readCommand :: Num b => a -> Expr b。如果这令人困惑,您应该阅读类型和类型类。您还需要Num (Var 3) 而不仅仅是Var 3,以便结果具有正确的类型。并且您需要更改Expr 的定义,以便NumBool 分别采用NumericExpr eBooleanExpr e,而不仅仅是e
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多