我一直在尝试使用GADT等创建完全类型化的Haskell DSEL,以实现全类型安全的AST。然而,正确类型化编译器需要涉及从Haskell类型到类型和值的映射(类型环境),这些内容可以被Haskell类型系统理解。C ++有Boost.Fusion库,其中包含这样的结构(类型->值映射,类型化值向量等)。Data.Tuple处理序列,但是否有Haskell版本的Boost.Fusion映射?
看看dependent-map包。虽然我自己没有使用过,但它似乎可以做到你所要求的。如果你需要真正使用类型(仅限于类型)相等性,则可能需要同意一个默认值或者使用TypeRep
作为键。
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
按类型插入元素。TypeMap
可以工作,但需要使用 unsafeCoerce
来让编译器相信右侧的类型与左侧(或 Data.Dynamic
)的 TypeRep
匹配。HList 也很有趣;fclabels 更像是提供了 zippers。我不需要对任意数据类型进行反射/数据通用编程,因此我认为 SYB 没有帮助。 - Jeremiah WillcockHList
(如果您静态地知道您的映射键)或类似的映射构造,使用Dynamic
在值中来避免unsafeCoerce
。 - Peter Wortmann[Int]
)。(Int->5, Float->"foo")
这样的映射值(不是提供全局映射的类型类)。我知道如何手动编写它(我想),但我想知道是否有人已经做过了。 - Jeremiah Willcock