您可以像这样实现关系代数:
Set<T> union(Set<T> a, Set<T> b) {
Set<T> res = new Set<T>();
for (T i: a) res.Add(i);
for (T i: b) res.Add(i);
return res;
}
Set<T> projection(Set<Pair<T,U>> a) {
Set<T> res = new Set<T>();
for (Pair<T,U> i: a) x.Add(i.first);
return res;
}
Set<T> selection(Set<T> a, Predicate<T> p) {
Set<T> res = new Set<T>();
for (T i: a) if (p.Call(i)) x.Add(i);
return res;
}
Set<Pair<T,U>> cross(Set<T> a, Set<U> b) {
Set<Pair<T,U>> res = new Set<Pair<T,U>>();
for (T i: a) for (U j: b) x.Add(Pair(i,j));
return res;
}
然后直接用代码写关系代数:
selection(projection(union(A,B)), isPositive)
基本上“投影”对应于“地图”,“选择”对应于“过滤器”。
显然不是每个代码都对应一个关系代数表达式。如果您将语言限制为没有while
,异常等。您可以将条件转换为选择,将多个嵌套循环转换为交叉产品,添加到联合等。形式化这是另一回事。
您可能更喜欢使用声明性更强的语言,例如 Haskell 或 ML;这是使用列表的实现:
type Database a = [a]
select :: (a -> Bool) -> Database a -> Database a
select = filter
projectFirst :: Database (a,b) -> Database a
projectFirst = map fst
projectSecond :: Database (a,b) -> Database b
projectSecond = map snd
union :: Database a -> Database a -> Database a
union = (++)