我有以下类型系列:
{-# LANGUAGE TypeFamilyDependencies #-}
type family Const arr r = ret | ret -> r where
Const (_ -> a) r = Const a r
Const _ r = r
这只是伪装的Const
函数,但GHC 8.2.1的注入性检查器并不认为它是单射的wrt。第二个论点:
* Type family equation violates injectivity annotation.
RHS of injective type family equation cannot be a type family:
Const (_ -> a) r = Const a r
* In the equations for closed type family `Const'
In the type family declaration for `Const'
|
4 | Const (_ -> a) r = Const a r
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
如果你遗漏了第一个案例,那就行了,这让我相信功能已经存在,但还不是很成熟。
我能否以其他方式制定这一点,以便GHC认识到注入?实际上对于这个稍微复杂的情况(所以arr
真正使用):
{-# LANGUAGE TypeFamilyDependencies #-}
type family ReplaceRet arr r = ret | ret -> r where
ReplaceRet (a -> b) r = a -> ReplaceRet b r
ReplaceRet _ r = r
答案 0 :(得分:4)
你建议
type family ReplaceRet arr r = ret | ret -> r where
ReplaceRet (a -> b) r = a -> ReplaceRet b r
ReplaceRet _ r = r
但
ReplaceRet (Int -> Bool) Char = Int -> Char
ReplaceRet Bool (Int -> Char) = Int -> Char
因此,给定ret
并不是真的,我们可以推导r
。我们无法拥有ret -> r
依赖关系。
我们可以改为arr ret -> r
,但据我所知,GHC不支持(但?)支持类型族的这种依赖。
Const a b
看起来好像尊重ret -> b
。然而,检测到这需要一个归纳证明,而GHC并不是那么聪明。确定注入性实际上非常棘手:请参阅第4.1节中的awkward cases in the paper以获得一些惊喜。为了克服这些问题,GHC必须设计得保守其接受的内容。