【问题标题】:Haskell: Rigid type variable errorHaskell:刚性类型变量错误
【发布时间】:2016-12-05 19:01:26
【问题描述】:

我的 haskell 代码中有这些信息:

data Symtable a = General a | Stack a

class Evaluable e where
eval :: (Num a, Ord a) => (Ident -> Maybe a) -> (e a) -> (Either String a)
typeCheck :: (Ident -> String) -> (e a) -> Bool

instance (Num a, Ord a) => Evaluable (NExpr a) where
eval _ (Const n) = Right n
typeCheck f f2 = True --to make the code compilable

它在 eval 的定义上给了我一个错误,因为它说:无法将类型 'e' 与 NExpr 匹配''e' 是一个严格的类型变量,由 ... eval::... 预期 e 是实际的下一秒

ident = 字符串和 Nexpr:

data NExpr n = Const n |
            Var Ident |
            Plus (NExpr n) (NExpr n) |
            Minus (NExpr n) (NExpr n) |
            Times (NExpr n) (NExpr n)

如何解决?

【问题讨论】:

  • 将实例更改为instance (Num a, Ord a) => Evaluable NExpr where ...
  • 然后它说:期望 Nexpr 再有一个参数 Evaluable 的第一个参数应该有种类 * 但有种类 * -> * @Alec

标签: haskell pattern-matching monads


【解决方案1】:

如果您提供的代码块确实与文件中的内容完全相同,那么您的缩进错误。修复缩进后,并遵循 Alec 关于实例定义的提示,此类型检查:

type Ident = String

data NExpr n = Const n |
            Var Ident |
            Plus (NExpr n) (NExpr n) |
            Minus (NExpr n) (NExpr n) |
            Times (NExpr n) (NExpr n)

data Symtable a = General a | Stack a

class Evaluable e where
  eval :: (Num a, Ord a) => (Ident -> Maybe a) -> e a -> Either String a
  typeCheck :: (Ident -> String) -> e a -> Bool

instance Evaluable NExpr where
  eval _ (Const n) = Right n
  typeCheck f f2 = True --to make the code compilable

注意where后面的定义需要缩进。

按照您的编写方式,您是在任何类或实例之外定义方法:

eval :: (Num a, Ord a) => (Ident -> Maybe a) -> e a -> Either String a
eval _ (Const n) = Right n

但在这种情况下,eval 的类型指定它必须为 all e a 定义,而不仅仅是NExpr a

【讨论】:

  • 缩进有问题
猜你喜欢
  • 1970-01-01
  • 2011-09-09
  • 1970-01-01
  • 2011-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-06
相关资源
最近更新 更多