我对以下代码中类型检查器的行为感到困惑:
{-# LANGUAGE ScopedTypeVariables
, TypeFamilies , MultiParamTypeClasses, FlexibleContexts #-}
class (BarClass (Foo a) a)=> FooClass a where
type Foo a
foo :: Foo a -> a
-- THIS WORKS:
theBarFooOf :: a -> Bar (Foo a) a
foo = bar $ theBarFooOf (undefined :: a)
-- THIS DOES NOT:
-- theBarFoo :: Bar (Foo a) a
-- foo = bar (theBarFoo :: Bar (Foo a) a)
class BarClass t r where
type Bar t r
bar :: (Bar t r) -> t -> r
第二个版本(foo
通过稍微简单的方法实现theBarFoo
)生成以下错误:
Could not deduce (Bar (Foo a) a ~ Bar (Foo a0) a0)
from the context (FooClass a)
bound by the class declaration for `FooClass'
at demo.hs:(5,1)-(15,42)
NB: `Bar' is a type function, and may not be injective
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Expected type: Bar (Foo a) a
Actual type: Bar (Foo a) a
In the first argument of `bar', namely
`(theBarFoo :: Bar (Foo a) a)'
In the expression: bar (theBarFoo :: Bar (Foo a) a)
In an equation for `foo': foo = bar (theBarFoo :: Bar (Foo a) a)
当实例头的范围内时,为什么值应该Bar (Foo a) a
是模棱两可a
的,但这工作正常:a -> Bar (Foo a) a
?这是一个错误吗?
我正在使用 GHC 7.6.3。