如何对关系进行列表理解?

How to do a list comprehension to a relation?

在我的代码中有以下两种方法:

public void AllDivisors(int max) {
     lrel[int,list[int]] div = [ <i,d> | int i <- [0 .. max], list[int] d <- GetDivisors(i)];
     println("<div>");
}

public list[int] GetDivisors(int n) {
      return [ p | p <- [1..n], n % p == 0];
}

第二个 (GetDivisors) 给出 n 和 returns 的除数列表作为 list[int]。接下来,我想在第一种方法 (AllDivisors) 中使用 lrel 将它们映射到 n 的值上。我试图使用列表理解一次性完成此操作,但这似乎不起作用。

rascal>GetDivisors(10);
list[int]: [1,2,5]

rascal>AllDivisors(10);
|project://Sevo/src/NumberEx.rsc|(189,1,<8,85>,<8,86>): Expected int, but    got list[int]
Advice: |http://tutor.rascal-mpl.org/Errors/Static/UnexpectedType/UnexpectedType.html|

我很难弄清楚 Rascal 期望 int 却得到 list[int] 的地方。我想它在 d <- GetDivisors(i) 中。如何在我的列表理解中生成正确的元组?

它位于:

list[int] d <- GetDivisors(i)

当您遍历 GetDivisors 的结果时,您得到的是 int 的结果,而不是 list[int] 的结果。因此,将其更改为 int d,或者只是 d(类型推断)应该就足够了。

你也可以这样做:

lrel[int,list[int]] div = [ <i,d> | int i <- [0 .. max], list[int] d := GetDivisors(i)];

这将 d 变量绑定到 GetDivisors

的结果

但对于这种情况,我会这样写:

div = [ <i, GetDivisors(i)> | i <- [0..max]];

你的问题的根源是 list[int] d <- GetDivisors(i)。因为 GetDivisors returns list[int] 它的元素是 int.

类型

所以第一个修正是:int d <- GetDivisors(i)

但现在您还必须将 div 的类型固定为 lrel[int,int] div

完整的例子就变成了:

public void AllDivisors(int max) {

    lrel[int,int] div = [ <i,d> | int i <- [0 .. max], int d <- GetDivisors(i)];
    println("<div>"); }

 public list[int] GetDivisors(int n) {
    return [ p | p <- [1..n], n % p == 0]; }

样式说明:我们通常让函数名以小写字母开头。