如何解决刚性类型变量绑定错误?

时间:2018-05-17 03:02:28

标签: haskell

我定义了Symbol数据类型,可以是BuiltInTypeSymbolProcedureSymbolProcedureSymbol可能有父类型Scope。所以我为Scope数据构造函数和ProcedureSymbol函数添加了parent类型约束。

data Symbol where 
     BuiltInTypeSymbol :: String -> Symbol
     ProcedureSymbol   :: Scope sc => String -> sc -> [Symbol] -> Symbol

name :: Symbol -> String
name (BuiltInTypeSymbol n) = n
name (ProcedureSymbol n _ _) = n 

parent :: Scope sc => Symbol -> Maybe sc
parent (ProcedureSymbol _ par _) = Just par
parent _ = Nothing

class Scope s where
    getName           :: s -> String
    getEnclosingScope :: Scope sc => s -> Maybe sc
    define            :: s -> Symbol -> s
    resolve           :: s -> String -> Maybe Symbol

当我尝试编译此代码时,出现以下编译错误:

SymbolTable.hs:13:36: error:
    * Couldn't match type `sc1' with `sc'
      `sc1' is a rigid type variable bound by
        a pattern with constructor:
          ProcedureSymbol :: forall sc.
                             Scope sc =>
                             String -> sc -> [Symbol] -> Symbol,
        in an equation for `parent'
        at SymbolTable.hs:13:9
      `sc' is a rigid type variable bound by
        the type signature for:
          parent :: forall sc. Scope sc => Symbol -> Maybe sc
        at SymbolTable.hs:12:11
      Expected type: Maybe sc
        Actual type: Maybe sc1
    * In the expression: Just par
      In an equation for `parent':
          parent (ProcedureSymbol _ par _) = Just par
    * Relevant bindings include
        par :: sc1 (bound at SymbolTable.hs:13:27)
        parent :: Symbol -> Maybe sc (bound at SymbolTable.hs:13:1)

如何编译此代码?

1 个答案:

答案 0 :(得分:1)

正如@David Young所指出的,你可以在你的Symbol构造函数中添加一个类型参数,如下所示:

{-# LANGUAGE GADTs #-}

data Symbol a where
     BuiltInTypeSymbol :: String -> Symbol a
     ProcedureSymbol   :: Scope a => String -> a -> [Symbol a] -> Symbol a

class Scope s where
    getName           :: s -> String
    getEnclosingScope :: Scope sc => s -> Maybe sc
    define            :: s -> Symbol s-> s
    resolve           :: s -> String -> Maybe (Symbol s)

name :: Symbol a -> String
name (BuiltInTypeSymbol n) = n
name (ProcedureSymbol n _ _) = n 

parent :: Scope sc => Symbol sc -> Maybe sc
parent (ProcedureSymbol _ par _) = Just par
parent _ = Nothing