解构成功的GADT记录功能失败

时间:2017-02-01 09:24:21

标签: haskell type-constraints gadt

我试图绕过GADT,我怀疑一些魔法正在发生,我不明白。

请考虑以下事项:

class C t

data T a where
  T :: (C a) => { getT :: a } -> T a

f :: C a => a -> ()
f = undefined

class D t where
  g :: t a -> ()

instance D T where
  g (T x) = f x

这一切都很好并且编译成功。

现在考虑对T:

稍微不同的实例定义
instance D T where
  g x = f (getT x)

这看起来与上面完全相同,但是存在编译错误。这里发生了什么?数据类型T没有存在变量,它只有一个简单的约束,它只是构造函数,但它就是它。

1 个答案:

答案 0 :(得分:7)

这里发生的是模式匹配

g (T x) = f x

告诉typechecker您已经满足约束C a,因此您可以使用f。如果没有模式匹配,则永远不会引入C a,因此无法满足约束条件。

它的作用使得值T something :: T a还包含C a的字典,并在T上进行模式匹配时可用。但是,使用getT并不能让您找到C a的字典(正如您从getT :: T a -> a的类型中看到的那样)。

对于后人,错误是

• No instance for (C a) arising from a use of ‘f’
  Possible fix:
    add (C a) to the context of
      the type signature for:
        g :: T a -> ()
• In the expression: f (getT x)
  In an equation for ‘g’: g x = f (getT x)
  In the instance declaration for ‘D T’