haskell -- 带有 TypeFamilies 扩展名的语句中代码"where"奇怪的歧义类型变量错误消息



有人知道为什么这段代码失败了吗?

{-# LANGUAGE NoMonomorphismRestriction,
             TypeFamilies #-}
module Test where
asExprTyp :: Expr γ =>
    γ α
    -> α
    -> γ α
asExprTyp x _ = x
int = undefined :: Integer
class Expr γ where
    a :: γ α
-- this works fine
b = a `asExprTyp` int
-- this fails
mcode = do
    return ()
    where b = a `asExprTyp` int

错误如下,

Test.hs:23:15:
    Ambiguous type variable `γ0' in the constraint:
    (Expr γ0) arising from a use of `a'
    Probable fix: add a type signature that fixes these type variable(s)
    In the first argument of `asExprTyp', namely `a'
    In the expression: a `asExprTyp` int
    In an equation for `b': b = a `asExprTyp` int
Failed, modules loaded: none.

我也不明白ghc有什么可抱怨的。我认为这可能是因为它试图给本地绑定一个单态类型,但是将NoMonoLocalBinds添加到语言pragma并没有改变任何东西。

然而,代码在最近的HEAD(7.3.20111026)下编译,加上它在没有启用TypeFamilies的情况下编译,这支持了错误假设。

如果这是一个真正的问题,你必须解决:添加类型签名使ghc高兴

好吧,这有点超出了我的理解范围,因为我从来没有在Haskell中使用过类型族。然而,你的例子实际上并没有使用类型族,所以我想我会看到当我从LANGUAGE pragma中删除TypeFamilies语言扩展时会发生什么。事实证明:它编译得很好!:)

所以它很可能是一个GHC错误。

话虽这么说,我稍微检查了一下,注意到以下代码在启用TypeFamilies时可以很好地编译:

mcode = do
            b
            return ()
        where b = a `asExprTyp` int

这可能是无意义的,因为它的推断类型是mcode :: (Expr m, Monad m) => m (),而不仅仅是mcode :: Monad m => m (),但我的观点是,只有当a的类型以某种方式与mcode的类型绑定时,GHC似乎才会高兴。

不确定这是否有帮助,但它绝对激起了我的好奇心!

最新更新