为什么 GHC 不能在 Rank 2 类型的 class 类型族上推断出类型相等?

Why can't GHC deduce type equality on a class type family in a Rank 2 type?

作为我正在经历的一个非常精简的版本:

{-# LANGUAGE ExplicitForAll #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeFamilies #-}
class ValueGen v where
  type Output v
  generate :: v -> Output v

instance ValueGen Integer where
  type Output (Integer) = Integer
  generate n = n + 1

newtype IntGenerator = Gen { generator :: forall v. ValueGen v => ((Output v) ~ Integer) => v }

myGen :: IntGenerator
myGen = Gen (3 :: Integer)

GHC给出的错误是

Could not deduce: v ~ Integer
from the context: (ValueGen v, Output v ~ Integer)
  bound by a type expected by the context:
            forall v. (ValueGen v, Output v ~ Integer) => v

如果我只是尝试通过类型相等性来限制 v,这很好用。

GHC 遇到了什么问题?如果已经通过输入 3 :: Integer 通知了限制,为什么还要尝试推断限制 v ~ Integer?限制检查不应该是Output Integer解析为Integer等于Integer然后pass吗?

摘要

我试图编写一个 2 级类型,其中包含两个 Pipeline class 实例,它们共享一些中间类型。基本想法是获得两条管道,例如

a|---|b  b|---|c

并生成一个新类型 Joined 然后它是 Pipeline

的一个实例
a|------------|c
a|---|b  b|---|c

问题是内部管道与内部 forall 一起存储,使用类型等于 Joined 类型参数的限制 - 但 GHC 似乎无法识别何时满足限制.

您所写的定义意味着 IntGenorator 您有:

If you give me an IntGenorator and think of some type v such that Output v ~ Integer then I will give you something of type v based on whatever is inside the IntGenorator

If for any type v such that Output v ~ Integer, you can give me something of type v then you can construct something of type IntGenorator

因为类型族不是单射的,所以可能有其他类型 v 而不是 Integer 这样 Output v ~ Integer (注意它们可能在 ghc 尚未编译的模块中或者还没有写)。因此 ghc 无法证明 vOutput v ~ Integer 的唯一类型是 Integer (或者更确切地说是实现 Num 的一些类型集)因此 3 :: Integer (或者而 3 :: Num a => a) 是 forall v. (Output v ~ Integer) => v.

类型的有效值

例如如果有人用 Output Char = Integer 添加了实例 ValueGen Char 怎么办?那么 3 肯定不是 Char 类型(除非有人实现 Num Char)所以你不能把它放在 IntGenerator