2

In my code I have the following two methods:

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

The second one (GetDivisors) gives the list of divisors for n and returns those as a list[int]. Next I want to map those on the values of n using a lrel in the first method (AllDivisors). I was trying to get this done in one go using a list comprehension, but this doesn't seem to work.

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|

I'm having a hard time figuring out where Rascal is expecting an int but getting a list[int]. I suppose it's in d <- GetDivisors(i). How can I generate the correct tuples in my list-comprehension?

Ruben Steins
  • 2,782
  • 4
  • 27
  • 48

2 Answers2

4

The root of your problem is list[int] d <- GetDivisors(i). Since GetDivisors returns list[int] its elements are of type int.

So the first fix is: int d <- GetDivisors(i).

But now you will also have to fix the type of div into lrel[int,int] div.

The complete example then becomes:

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

A note on style: we usually let function names start with a lower case letter.

Paul Klint
  • 1,418
  • 7
  • 12
  • 2
    I really wanted the lrel to have type [int, list[int]] though. Tuples of int and list[int]. And for you remark on style: I'll try to do better :). I spend most of my days in C#, so those conventions come naturally. – Ruben Steins Nov 27 '17 at 11:02
3

It is in:

list[int] d <- GetDivisors(i)

when you iterate over the results of GetDivisors you are getting int's not, list[int]'s. So changing that to int d, or just d (type inference) should be good enough.

you could also do this:

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

This binds the d variable to the result of GetDivisors

But for this case I would write it as follows:

div = [ <i, GetDivisors(i)> | i <- [0..max]];
Davy Landman
  • 15,109
  • 6
  • 49
  • 73