我假设可以使用类型算术解决以下问题,但尚未找到解决方案。
问题
我有一个从字符串到值的有限映射(使用 Tries 作为实现),我从二进制/文本文件(json、xml、...)解析。
type Value = ...
type Attributes = Data.Trie Value
data Object = Object Attributes
每个映射具有相同类型的值,但不同的键集。我将具有相同键集的映射分组在一起,以防止必须一直进行类型切换我有一个需要某些键的专用功能:
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 = ...
这可行,但有两个缺点:
- Object 的同构列表现在变得异构,即我不能再拥有一个列表 [Object]。
我需要编写很多样板来获取/设置属性:
get :: Object a -> Attributes get (T1 a) = a get (T2 a) = a ...
问题
- 有没有更好的方法来根据 ADT 的构造函数专门化函数?
我怎样才能重新获得拥有列表 [对象] 的能力?是否有专门的 Dynamic 版本只允许某些类型?我想过再次包装对象,但这会增加很多样板。例如,
数据 TObject = TT1 T1 | TT2 T2 ...
我需要的是:
get :: a -> TObject -> Object a
这样我就可以得出:
collect :: a -> [TObject] -> [Object a]
我查看了 HList 但我认为它不适合我的问题。特别是,因为 [Object] 中的类型顺序在编译时是未知的。
在我看来,这可以使用函数依赖/类型算术来解决,但我还没有找到一个好的方法。