Haskell 我能';我不能让基于GADT的玩具动态类型使用参数化类型
因此,为了帮助我理解一些更高级的Haskell/GHC特性和概念,我决定采用一种基于GADT的动态类型数据实现,并将其扩展到参数类型。(很抱歉,这个例子太长了。) 按照我的阅读方式,编译器无法理解在Haskell 我能';我不能让基于GADT的玩具动态类型使用参数化类型,haskell,gadt,curry-howard,Haskell,Gadt,Curry Howard,因此,为了帮助我理解一些更高级的Haskell/GHC特性和概念,我决定采用一种基于GADT的动态类型数据实现,并将其扩展到参数类型。(很抱歉,这个例子太长了。) 按照我的阅读方式,编译器无法理解在inclusive::Equal a b->Equal(f a)(f b)中,a和b对于非底部值必须相等。因此,我尝试了归纳::Equal a a->Equal(fa)(fa),但在匹配类型::TypeRep a->TypeRep b->Maybe(Equal a b)的定义中,这也失败了: 。/sr
inclusive::Equal a b->Equal(f a)(f b)
中,a
和b
对于非底部值必须相等。因此,我尝试了归纳::Equal a a->Equal(fa)(fa)
,但在匹配类型::TypeRep a->TypeRep b->Maybe(Equal a b)
的定义中,这也失败了:
。/src/Dyn.hs:66:60:
无法推断(a2~a1)
从上下文(a~[a1])
由具有构造函数的模式绑定
列表::全部a。TypeRep a->TypeRep[a],
在“匹配类型”的等式中
在../src/Dyn.hs:66:13-18
或来自(b~[a2])
由具有构造函数的模式绑定
列表::全部a。TypeRep a->TypeRep[a],
在“匹配类型”的等式中
在../src/Dyn.hs:66:22-27
`a2'是一个刚性类型变量,由
具有构造函数的模式
列表::全部a。TypeRep a->TypeRep[a],
在“匹配类型”的等式中
在../src/Dyn.hs:66:22
`a1'是一个刚性类型变量,由
具有构造函数的模式
列表::全部a。TypeRep a->TypeRep[a],
在“匹配类型”的等式中
在../src/Dyn.hs:66:13
预期类型:TypeRep a1
实际类型:TypeRep a
在'matchTypes'的第二个参数中,即'b'
在“()”的第二个参数中,即“(匹配类型a b)”
将matchTypes::TypeRep a->TypeRep b->Maybe(等于ab)
的类型更改为生成matchTypes::TypeRep a->TypeRep b->Maybe(等于aa)
不起作用(只需将其作为命题阅读即可)。matchTypes::TypeRep a->TypeRep a->Maybe(等于a)
(另一个琐碎的命题,据我所知,这需要fromDynamic'的用户知道TypeRep a中包含的a)
所以,我被难住了。这里有关于如何前进的指针吗?问题是您的模式的通配符模式丢失了相等信息。如果你以这种方式编码归纳法,你就不能写出一个覆盖所有情况的(有限的)模式集合。解决方案是将归纳法从数据类型移到定义的值中。相关变化如下所示:
data Equal a b where
Reflexivity :: Equal a a
induction :: Equal a b -> Equal (f a) (f b)
induction Reflexivity = Reflexivity
matchTypes (List a) (List b) = induction <$> matchTypes a b
matchTypes (Maybe a) (Maybe b) = induction <$> matchTypes a b
fromDynamic' :: TypeRep a -> Dynamic -> Maybe a
fromDynamic' target (Dyn source value) =
case matchTypes source target of
Just Reflexivity -> Just value
Nothing -> Nothing
数据等于a b,其中
自反性:等于a
归纳法:等于AB->等于(FA)(FB)
感应自反性=自反性
匹配类型(列表a)(列表b)=感应匹配类型a b
匹配类型(可能a)(可能b)=归纳匹配类型a b
fromDynamic'::TypeRep a->Dynamic->Maybe a
fromDynamic“目标(动态源值)=
案例匹配类型源目标
正义反身->正义价值
无->无
这样一来,fromDynamic'
中的模式是详尽无遗的,但没有任何信息丢失通配符。你难道不能放下inclusion
构造函数,推导出相同的原理inclusion::Eq a b->Eq(f a)(f b);归纳自反性=自反性
?是的,我一直怀疑通配符。有一次,我试图通过编写一个normalizeeEqual::Equal a b->Equal a
函数来解决这个问题,该函数将所有归纳
案例转换为自反性
,但由于我记不起的原因,它也失败了……您确实可以从这种类型规范化数据数据EqI::*->*->*->*->*其中ReflI::EqI a;RespI::EqI a b->EqI(f a)(f b)
此类型中的数据数据EqR::*->*->*->*其中Refl::EqR a a a
如下:事实::EqI a b->EqR a b;事实反射=反射;事实(RespI p)=Refl->Refl
@sacundim的案例事实p我想你可能会让normalizeeEqual::Equal a b->Equal a b
工作,但你建议的类型在我看来很奇怪。您总是可以构造一个类型为等于a
的值——提供a
等于其他值的证明似乎是不必要的。
../src/Dyn.hs:105:34:
Could not deduce (a2 ~ b)
from the context (a1 ~ f a2, a ~ f b)
bound by a pattern with constructor
Induction :: forall a b (f :: * -> *).
Equal a b -> Equal (f a) (f b),
in a case alternative
at ../src/Dyn.hs:105:13-23
`a2' is a rigid type variable bound by
a pattern with constructor
Induction :: forall a b (f :: * -> *).
Equal a b -> Equal (f a) (f b),
in a case alternative
at ../src/Dyn.hs:105:13
`b' is a rigid type variable bound by
a pattern with constructor
Induction :: forall a b (f :: * -> *).
Equal a b -> Equal (f a) (f b),
in a case alternative
at ../src/Dyn.hs:105:13
Expected type: a1
Actual type: a
In the first argument of `Just', namely `value'
In the expression: Just value
In a case alternative: Just (Induction _) -> Just value
../src/Dyn.hs:66:60:
Could not deduce (a2 ~ a1)
from the context (a ~ [a1])
bound by a pattern with constructor
List :: forall a. TypeRep a -> TypeRep [a],
in an equation for `matchTypes'
at ../src/Dyn.hs:66:13-18
or from (b ~ [a2])
bound by a pattern with constructor
List :: forall a. TypeRep a -> TypeRep [a],
in an equation for `matchTypes'
at ../src/Dyn.hs:66:22-27
`a2' is a rigid type variable bound by
a pattern with constructor
List :: forall a. TypeRep a -> TypeRep [a],
in an equation for `matchTypes'
at ../src/Dyn.hs:66:22
`a1' is a rigid type variable bound by
a pattern with constructor
List :: forall a. TypeRep a -> TypeRep [a],
in an equation for `matchTypes'
at ../src/Dyn.hs:66:13
Expected type: TypeRep a1
Actual type: TypeRep a
In the second argument of `matchTypes', namely `b'
In the second argument of `(<$>)', namely `(matchTypes a b)'
data Equal a b where
Reflexivity :: Equal a a
induction :: Equal a b -> Equal (f a) (f b)
induction Reflexivity = Reflexivity
matchTypes (List a) (List b) = induction <$> matchTypes a b
matchTypes (Maybe a) (Maybe b) = induction <$> matchTypes a b
fromDynamic' :: TypeRep a -> Dynamic -> Maybe a
fromDynamic' target (Dyn source value) =
case matchTypes source target of
Just Reflexivity -> Just value
Nothing -> Nothing