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_Algebraic Data Types - Fatal编程技术网

Haskell GADT或幻影类型检查函数调用的类型,但保持类型的同质性

Haskell GADT或幻影类型检查函数调用的类型,但保持类型的同质性,haskell,algebraic-data-types,Haskell,Algebraic Data Types,我假设下面的问题可以用类型算术解决,但还没有找到解决方案 问题 我有一个从字符串到值的有限映射(使用Tries作为实现),我从二进制/文本文件(json、xml等)解析它 每个贴图具有相同类型的值,但不具有相同的键集。 我将具有相同一组键的地图分组在一起,以防止在我具有需要特定键的专门功能时必须键入开关: data T1 data T2 ... data Object a where T1 :: Attributes -> Object T1 T2 :: Attribu

我假设下面的问题可以用类型算术解决,但还没有找到解决方案

问题 我有一个从字符串到值的有限映射(使用Tries作为实现),我从二进制/文本文件(json、xml等)解析它

每个贴图具有相同类型的值,但不具有相同的键集。 我将具有相同一组键的地图分组在一起,以防止在我具有需要特定键的专门功能时必须键入开关:

data T1
data T2 
...

data Object a where
    T1 :: Attributes -> Object T1
    T2 :: Attributes -> Object T2
    ...
这让我可以写一些东西,比如:

f1 :: Object T1 -> ...
而不是

f1 :: Object ->
f1 o | check_if_T1 o = ...
这是可行的,但有两个缺点:

  • 对象的同质列表现在变得异质,即我不能再拥有列表[对象]
  • 我需要编写大量样板文件来获取/设置属性:

    get :: Object a -> Attributes
    get (T1 a) = a
    get (T2 a) = a
    ...
    
  • 问题:
  • 是否有更好的方法根据ADT的构造函数专门化函数
  • 我怎样才能重新获得拥有列表[对象]的能力?是否有只允许某些类型的Dynamic的专用版本? 我曾考虑再次包装该对象,但这会增加很多样板文件。比如说,

    数据对象=TT1 T1 | TT2 T2

  • 我需要的是:

    get :: a -> TObject -> Object a
    
    这样我就可以得出:

    collect :: a -> [TObject] -> [Object a]
    
    我查看了HList,但我认为它不适合我的问题。特别是,因为编译时不知道[Object]中类型的顺序

    在我看来,这似乎可以用函数依赖/类型算法来解决,但我还没有找到一个好方法

  • 如果所有构造函数都返回一个单态
    对象
    类型,并且没有递归,那么您可能需要考虑使用单独的类型。而不是

    data T1
    data T2
    
    data Object a where
        T1 :: Attributes -> Object T1
        T2 :: Attributes -> Object T2
    
    考虑

    data T1 = T1 Attributes
    data T2 = T2 Attributes
    
  • Dynamic
    是一种方法,使用上面的方法,您只需添加
    派生Typeable
    即可。或者,您可以手动完成:

    data TSomething = It's1 T1 | It's2 T2
    
    getT1s :: [TSomething] -> [T1]
    getT2s :: [TSomething] -> [T2]
    getT1s xs = [t1 | It's1 t1 <- xs]
    getT2s xs = [t2 | It's2 t2 <- xs]
    

  • 什么是领带?由于对象的数量有限,您不能将字符串键解析为适当的类型,并为每个对象类型使用新的对象构造函数吗?我不知道你为什么需要GADTs@jberryman当前位置GADT只是一个想法。主要问题是,我希望能够在ADT上编写特殊和通用函数,并在集合中使用该对象。使用多个结构将导致HLIST。特殊::对象T1->。。。非特殊::对象?->@Chronos,你最后用的是什么设计?我最近尝试了相同的结构,但仍在寻找类似的解决方案。
    data TSomething = It's1 T1 | It's2 T2
    
    getT1s :: [TSomething] -> [T1]
    getT2s :: [TSomething] -> [T2]
    getT1s xs = [t1 | It's1 t1 <- xs]
    getT2s xs = [t2 | It's2 t2 <- xs]
    
    deriving Typeable T1
    deriving Typeable T2
    
    -- can specialize at the call-site to
    -- getTs :: [Dynamic] -> [T1] or
    -- getTs :: [Dynamic] -> [T2]
    getTs :: Typeable a => [Dynamic] -> [a]
    getTs xs = [x | Just x <- map fromDynamic xs]