Haskell:刚性类型变量错误

时间:2016-12-05 19:01:26

标签: haskell pattern-matching monads

我的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 :: ... expect ea actual Nexpr a

ident = string和Nexpr:

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

如何解决?

1 个答案:

答案 0 :(得分:4)

如果您提供的代码块确实与文件中的内容完全相同,那么您的缩进就会出错。在修复缩进之后,按照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的类型指定必须为所有 e a定义,而不仅仅是NExpr a