haskell - 不理解为什么这个关联的类型示例需要更多的推断

时间:2011-09-12 00:04:06

标签: haskell typeclass associated-types

考虑以下代码,

data MyBaseExpr α where
    ConstE :: Show α => α -> MyBaseExpr α

class Monad  => MyMonadCls  where
    type ExprTyp  :: * -> *
    var :: String -> ExprTyp  α ->  (ExprTyp  α)

expTypArg :: forall  α. MyMonadCls  => ExprTyp  α ->  α
expTypArg a = undefined

-- dummy type which will be used as an instance
newtype A  α = A ( α)

然后,如果尝试使用expTypeArg函数编写实例,

instance forall . (Monad , Monad (A )) => MyMonadCls (A ) where
    type ExprTyp (A ) = MyBaseExpr
    var nme init@(expTypArg -> typb) =
        return init

编译器抱怨

Couldn't match type `ExprTyp 0' with `MyBaseExpr'
Expected type: ExprTyp (A ) α
  Actual type: ExprTyp 0 α

但是,如果添加一些范围类型表达式,

instance forall . (Monad , Monad (A )) => MyMonadCls (A ) where
    type ExprTyp (A ) = MyBaseExpr
    var nme init@((expTypArg :: MyMonadCls (A ) =>
                   ExprTyp (A ) α ->
                   (A  α)) -> typb) =
        return init
然后它解决得很好。解决ExprTyp == MyBaseExpr的{​​{1}}问题是什么?

修改

非常感谢,丹尼尔!在注意到只需要强制执行expTypArg类型之后,这是一种消除部分废弃物的方法。

1 个答案:

答案 0 :(得分:3)

ExprTyp不是(必然)一个内射型函数。这意味着,ExprType m类型的某些内容并未确定m - 可能还有nExprType n = ExprType mexpTypArg。这使得read的类型有点棘手:它以相同的方式使用返回类型多态,例如,read,所以你需要在其结果中给出额外的类型注释与{{1}}有关的情况。