Haskell中与Boost.Fusion相当的库

10
我一直在尝试使用GADT等创建完全类型化的Haskell DSEL,以实现全类型安全的AST。然而,正确类型化编译器需要涉及从Haskell类型到类型和值的映射(类型环境),这些内容可以被Haskell类型系统理解。C ++有Boost.Fusion库,其中包含这样的结构(类型->值映射,类型化值向量等)。Data.Tuple处理序列,但是否有Haskell版本的Boost.Fusion映射?

下投票的原因是什么? - Jeremiah Willcock
当你描述一个“编译器”时,你正在从哪里/到哪里进行编译?如果你有GADT,你真的在为它编写解释器,还是从GADT到例如C代码的函数? - sclv
无论是将类型化的AST转换为其他形式,还是运行它,都会出现相同的问题。 - Jeremiah Willcock
是啊,为什么要踩这个问题呢?在我看来,这是一个很好的问题。 - Claudiu
只是出于好奇 - 这可能不是适当的论坛,但我认为这个问题并没有像你想象的那样经常出现?不过,看一下这个:http://okmij.org/ftp/tagless-final/index.html#tc-GADT - sclv
4个回答

10

看看dependent-map包。虽然我自己没有使用过,但它似乎可以做到你所要求的。如果你需要真正使用类型(仅限于类型)相等性,则可能需要同意一个默认值或者使用TypeRep作为键。


4
首先,显而易见的答案是您可以使用 base 库中的 Typeable 轻松编写“类型-值映射”:
import Data.Typeable
import Data.Map

type TypeMap a = Map TypeRep a

insertT :: Typeable k => k -> a -> Map k a -> Map k a
insertT v = insert (typeOf k)

lookupT :: Typeable k => k -> a -> Map k a -> Map k a
lookupT v = lookup (typeOf k)

现在您可以使用代码insertT (undefined :: Int) 5按类型插入元素。
但是看起来Fusion并不像你想要的东西。它似乎允许您构建适用于任意数据结构的代码?在Haskell中,这被称为“废除锅炉板”通用编程。有关详细信息,请参见论文hackage,但它允许您编写处理任意数据结构并提取给定类型值的代码。
我看到Fusion的其他几个方面可能可以使用库(如HList或可能的fclabels)模拟。但是,没有查看您实际需要的内容,很难说得更多。

你的 TypeMap 可以工作,但需要使用 unsafeCoerce 来让编译器相信右侧的类型与左侧(或 Data.Dynamic)的 TypeRep 匹配。HList 也很有趣;fclabels 更像是提供了 zippers。我不需要对任意数据类型进行反射/数据通用编程,因此我认为 SYB 没有帮助。 - Jeremiah Willcock
嗯,我不确定你是否希望问题中的值具有其索引类型。如果您想要这个,您可能应该使用HList(如果您静态地知道您的映射键)或类似的映射构造,使用Dynamic在值中来避免unsafeCoerce - Peter Wortmann

3

如前所述,dependent-map 似乎是地图方面的正确选择,但我建议查看 hlistHArray 接口作为手动搬弄元组的替代品。


1
你正在寻找 Data.Map 和列表吗?(例如 [Int])。

不行,因为元素需要具有不同的类型,而这里的键是类型。我想要的是像(Int->5, Float->"foo")这样的映射值(不是提供全局映射的类型类)。我知道如何手动编写它(我想),但我想知道是否有人已经做过了。 - Jeremiah Willcock
@NathanHowell:你能把这个作为答案发一下吗?我会去看看,但从文档上看,它似乎就是我要的。 - Jeremiah Willcock

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接