如果我是正确的,只有完整的应用类型才能在compdata
中使用。
这样做的根本限制是什么?
有办法解决这个问题吗?
import Data.Constraint
import Data.Comp.Ops
import Data.Comp.Sum
import Data.Comp.Term
data Val a = Val Int deriving Functor
data Add a = Add a a deriving Functor
-- Val is a subtype of Val :+: Add
works = Dict :: Dict (Val :<: (Val :+: Add))
-- Does not work :<: requires fully applied types.... !!
notworks = Dict :: forall f . Functor f => Dict (f :<: (f :+: Add))
可能的答案:p80
最重要的限制是
:≺:
仅适用于地面类型, 即任何一方都不得包含变数。这是例外 如果签名上,我们不能排除歧义和重复:≺:
的任何一方都没有完全实例化。例如,我们可能不会 派生Val :≺: f :+: Val
,因为如果f
由Val
实例化, 包含将是不明确的。
确实,像
这样的一般功能notworks = Dict :: forall f . Functor f => Dict (f :<: (f :+: Add))
无法正常工作。
可能的答案?
然而,似乎给出了证明s :<: f
和f :<: g
,我应该能够形成复合(因为注入被保留)s :<: g
....
编辑:某些'完成'的内容
data ReflI
data CompI
data InjectProof a io where
ReflS :: Dict (f :<: g) -> InjectProof ReflI f g
Comp :: InjectProof a f g -> InjectProof b g h -> InjectProof CompI f h
class Injectable i f g where
injectProof :: InjectProof i f g
instance (f :<: g) => Injectable ReflI f g where
injectProof = ReflS Dict
instance (Injectable i f g, Injectable j g h) => Injectable CompI f h where
injectProof = Comp (injectProof :: InjectProof i f g) (injectProof :: InjectProof j g h)
可能的答案#2?
我们不能说用某种级别装饰类型
(Val,N) :≺: ((f, Suc N) :+: (Val, Suc N))
然后它是通过构造单射,并且我们可以推迟给出证明每个构造函数在我们应用它时分开,允许剥离索引。