Haskell (如何)在“依赖图”GADT中有多态性值?
任何人都知道如何/是否有可能在以下方面扩展Haskell (如何)在“依赖图”GADT中有多态性值?,haskell,gadt,reflex,Haskell,Gadt,Reflex,任何人都知道如何/是否有可能在以下方面扩展FooGADT: 与 (或类似的东西)以允许在 当我尝试时,会出现如下类型的错误: exp-dep-map.hs:20:1: error: • Couldn't match type ‘a’ with ‘b’ ‘a’ is a rigid type variable bound by the type signature for: geq :: forall a b. Foo a -> Foo
Foo
GADT:
与
(或类似的东西)以允许在
当我尝试时,会出现如下类型的错误:
exp-dep-map.hs:20:1: error:
• Couldn't match type ‘a’ with ‘b’
‘a’ is a rigid type variable bound by
the type signature for:
geq :: forall a b. Foo a -> Foo b -> Maybe (a := b)
at exp-dep-map.hs:20:1-20
‘b’ is a rigid type variable bound by
the type signature for:
geq :: forall a b. Foo a -> Foo b -> Maybe (a := b)
at exp-dep-map.hs:20:1-20
Expected type: Maybe (a := b)
Actual type: Maybe (a :~: a)
• In a stmt of a 'do' block: return Refl
In the expression: do return Refl
In an equation for ‘geq’: geq ANum ANum = do return Refl
• Relevant bindings include
geq :: Foo a -> Foo b -> Maybe (a := b)
(bound at exp-dep-map.hs:20:1)
|
20 | deriveGEq ''Foo
| ^^^^^^^^^^^^^^^^^^^^
编辑:我继续与echatav和isovector(GitHub用户名)一起研究这个问题,我们能够进一步解决这个问题,我们还发现手动定义
GEq
和GCompare
实例很有帮助。谢谢你,@rampion,你的回答也证实了我们的发现
尽管对于大型记录类型,手动定义这些记录远远不够理想。我想知道TemplateHaskell生成器(deriveGCompare
,deriveGEq
){是否需要更新才能处理多态性
另外,我发现对于我当前的用例,我正在寻找的pol'ism实际上更接近于
data Foo n a where
AnInt :: Foo n Int
AString :: Foo n String
ANum :: (Num n, Typeable n, Show n) => Foo n n
手工定义的实例在这里也很管用,但再一次,效果并不理想
instance GEq (Foo n) where
geq AnInt AnInt = return Refl
geq AString AString = return Refl
geq ANum ANum = return Refl
geq _ _ = Nothing
instance GCompare (Foo n) where
gcompare AnInt AnInt = GEQ
gcompare AnInt _ = GLT
gcompare _ AnInt = GGT
gcompare AString AString = GEQ
gcompare AString _ = GLT
gcompare _ AString = GGT
gcompare (ANum :: Foo n a) (ANum :: Foo n b) = (eqT @a @b) & \case
Just (Refl :: a :~: b) -> GEQ
Nothing -> error "This shouldn't happen"
gcompare ANum _ = GLT
gcompare _ ANum = GGT
试图使用TH,(例如,deriveGEq'Foo
或deriveGEq'(Foo n)
)我遇到了实物问题
exp-dep-map.hs:39:1: error:
• Expecting one more argument to ‘Foo’
Expected kind ‘* -> *’, but ‘Foo’ has kind ‘* -> * -> *’
• In the first argument of ‘GEq’, namely ‘Foo’
In the instance declaration for ‘GEq Foo’
|
39 | deriveGEq ''Foo
| ^^^^^^^^^^^^^^^^^^^^
可能相关:模板haskell使您很难看到发生了什么,因此我建议您滚动自己的
GEq
实例,以便更好地理解错误
看看:
我们对a
或b
没有任何进一步的限制,因此我们需要仅在GADT的构造函数上证明(或反驳)类型相等性
上面的ANum
没有告诉我们
但是,如果我们在ANum
-Typeable
ANum :: (Num n, Typeable n) => n -> Foo n
现在我们可以使用来见证类型相等
geq (ANum _) (ANum _) = eqT
谢谢你的指点!同时,与echatav和isovector(GH名称)一起,我们能够进一步解决这个问题,我们还发现手动定义
GEq
和GCompare
实例有帮助。尽管对于大型记录类型来说,它远不是理想的。我想知道TH生成器是否需要更新以处理多态性。此外,我发现对于我当前的用例,我正在寻找的pol'ism实际上更接近数据foon a,其中AnInt::Foo n Int;ANum::(Num n,Typeable n)=>Foo n n
。手工定义的实例在这里也很管用,但再一次,效果并不理想。试图使用TH,(例如,deriveGEq'Foo
或deriveGEq'(Foo n)
)我遇到了实物问题。可能相关:
exp-dep-map.hs:40:19: error: parse error on input ‘Foo’
|
40 | deriveGEq ''(Foo n)
| ^^^
class GEq f where
geq :: f a -> f b -> Maybe (a := b)
ANum :: (Num n, Typeable n) => n -> Foo n
geq (ANum _) (ANum _) = eqT