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

时间:2017-11-27 10:31:30

标签: list-comprehension rascal

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

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的除数列表,并将其作为list[int]返回。接下来,我想在第一个方法(AllDivisors)中使用n映射lrel的值。我试图使用列表理解一次完成这项工作,但这似乎不起作用。

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)。如何在列表推导中生成正确的元组?

2 个答案:

答案 0 :(得分:4)

问题的根源是list[int] d <- GetDivisors(i)。由于GetDivisors返回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]; }

关于样式的注释:我们通常让函数名称以小写字母开头。

答案 1 :(得分:3)

它在:

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]];