2011-11-29 61 views
10

我一直在玩一个完全的类型安全AST等创建使用GADTs和Haskell中完全类型DSEL,它似乎是做了正确输入编译器要求的结构,如从哈斯克尔类型的地图到类型和值(类型化的环境)以及Haskell类型系统都可以理解的类型和值。 C++具有Boost.Fusion库,其结构像这些(类型 - >值映射,类型值向量等)。 Data.Tuple处理序列,但Haskell版本的东西,如Boost.Fusion map s?哈斯克尔相当于Boost.Fusion

+0

downvote的原因是什么? –

+0

当你描述一个“编译器”时,你要从哪个表编译?如果你有GADT,你是真的在为它编写解释器,还是从GADT到例如C代码的函数? – sclv

+0

要么 - 将任何类型的AST翻译成其他任何东西或运行它的任何问题都会出现。 –

回答

10

看那dependent-map包。我自己并没有使用它,但它似乎是按照你所要求的。如果您需要真正使用类型(和类型)相等,那么您可能需要同意默认值或使用TypeRep作为关键字。

1

您是否在寻找Data.Map,并列出? (例如[Int])。

+0

没有,因为元素需要有不同的类型,这里的键类型。我想要一个像'(Int-> 5,Float - >“foo”)'这样的映射在一个值中(而不是一个给出全局映射的类型类)。我知道如何手写(我认为),但我想知道是否有人已经这样做了。 –

+1

尝试从属地图包:http://hackage.haskell.org/package/dependent-map –

+0

@NathanHowell:能否请您发布此作为答案?我会检查它,但它从文档看起来像它是我所要求的。 –

4

首先,全太明显的答案是,你可以很容易地写了一个“类型 - >值映射”使用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按类型插入元素。

但看融合,这并没有真正的样子,你可能是什么之后。它似乎允许您构建在任意数据结构上工作的代码?这就是Haskell被称为“Scrap your Boilerplate”的泛型编程。有关详细信息,请参阅papershackage,但它允许您编写处理任意数据结构并挑选给定类型值的代码。

我看到的Fusion的其他一些内容可能可以使用库来模拟,例如HList或可能fclabels。但它真的很难说更多没有看看你真正需要什么。

+0

你的'TypeMap'可以工作,但需要一个'unsafeCoerce'来说服编译器,右边的类型和左边的TypeRep(或Data.Dynamic)匹配。 HList看起来也很有趣; fclabels看起来更像它提供的拉链。我不需要针对任意数据类型的反射/数据泛型编程,所以我不认为SYB会有所帮助。 –

+0

那么,我不确定你是否想要这个值有其索引类型。如果你需要,你可能要么应该使用'HList'(如果你知道静态地图的键),或者使用'Dynamic'中的类似地图构造绕过'unsafeCoerce'。 –

3

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