Haskell: 刚性类型变量错误

Haskell: Rigid type variable error

我的 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 实际 Nexpr a

ident = 字符串和 Nexpr:

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

如何解决?

如果您提供的代码块确实与文件中的完全一致,那么您的缩进有误。修复缩进后,按照 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后面的定义需要缩进

按照你写的方式,你在任何 class 或实例之外定义了一个方法:

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

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