Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell (如何)在“依赖图”GADT中有多态性值?_Haskell_Gadt_Reflex - Fatal编程技术网

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