实现关系代数的语言特性

时间:2008-10-04 15:20:47

标签: orm scala dsl type-systems database-relations

我一直在尝试在Scala中对关系代数进行编码(据我所知,它具有最先进的类型系统之一)并且似乎找不到找到我想要的方法。

由于我不熟悉编程语言设计的学术领域,我真的不知道要寻找什么功能。

那么实现静态验证的关系代数需要哪些语言功能以及具有这些功能的语言?

部分要求: 元组是一个函数,它将名称从有问题的元组的静态定义的有效名称集合映射到名称指定的类型的值。让我们调用这个名称类型设置域名。

一个关系是一组具有相同域的元组,因此任何元组的范围在集合中都是唯一的

到目前为止,模型可以简单地通过

在Scala中建模
trait Tuple
trait Relation[T<Tuple] extends Set[T]

Tuple中的vals,vars和defs是上面定义的名称类型集。但是在Tuple中应该有两个同名的defs。此外,vars和impure defs也应该受到限制。

现在是棘手的部分:

两个关系的连接是一种关系,其中元组的域是来自操作数元组的域的并集。这样只保留了具有相同范围的元组域的元组。

def join(r1:Relation[T1],r2:Relation[T2]):Relation[T1 with T2]

应该这样做。

Relation的投影是一种关系,其中元组的域是操作数元组域的子集。

def project[T2](r:Relation[T],?1):Relation[T2>:T]

这是我不确定是否有可能找到溶剂的地方。你怎么看?定义项目需要哪些语言功能?

上述隐含的原因是API必须可用。层板和样板层是不可接受的。

5 个答案:

答案 0 :(得分:6)

您要求的是能够在结构上将类型定义为另外两种类型(原始关系和投影定义)的差异。老实说,我想不出任何可以让你这样做的语言。类型可以是结构上的累积(A with B),因为A with BAB的结构子类型。但是,如果您考虑一下,类型操作A less B实际上是A超类型,而不是子类型。你在自然协变类型上要求一个任意的,逆变的类型关系。甚至还没有证明某种事物在名义存在类型上是合理的,更不用说结构声明点类型了。

之前我曾进行过这种建模,我采用的路线是将投影约束到三个域中的一个:P == TP == { {1}},{F} where F in T == P。第一个是投影等效于输入类型,这意味着它是一个无操作({$_1} where $_1 anonymous)。第二个是说投影是输入类型中包含的单个字段。第三个是棘手的。这是说你允许声明一些匿名类型SELECT *,它与输入类型没有静态关系。据推测,它将包含委托给输入类型的字段,但我们无法强制执行。这大致是LINQ采取的策略。

抱歉,我无法提供更多帮助。我希望有可能做你所要求的,它会打开很多非常简洁的可能性。

答案 1 :(得分:2)

Tutorial D与语言的关系理论一样简单且紧密地对齐。

答案 2 :(得分:1)

HaskellDB有一些想法如何创建类型安全的关系代数DSL,你可能会发现它很有用。

答案 3 :(得分:1)

也许你从这里发现有用的东西: http://research.microsoft.com/en-us/um/people/simonpj/papers/list-comp/list-comp.pdf

它显示了如何将“分组依据”和“排序依据”添加到列表推导中。

答案 4 :(得分:0)

我认为我已经决定只使用正常的设施来为项目部分进行地图收集。客户端只需指定一个函数[T<:Tuple](t:T) => P

通过一些java技巧来获取P的类我应该能够使用反射来实现查询逻辑。

对于连接,我可能会使用DynamicProxy来实现映射功能。

作为奖励,我可能能够将API与Scalas特殊用于语法一起使用。