2017-11-27 3 views
2

In meinem Code habe ich die folgenden zwei Methoden:Wie man ein Listenverständnis zu einer Beziehung macht?

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

Die zweite (GetDivisors) gibt die Liste von Teilern für n und gibt diese als list[int]. Als nächstes möchte ich diese auf die Werte von n mit einem lrel in der ersten Methode (AllDivisors) zuordnen. Ich habe versucht, dies auf einmal mit einem Listenverständnis zu erreichen, aber das scheint nicht zu funktionieren.

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| 

Ich habe eine harte Zeit, herauszufinden, wo Rascal ist ein int erwarten aber eine list[int] bekommen. Ich nehme an, es ist in d <- GetDivisors(i). Wie kann ich die richtigen Tupel in meinem Listenverständnis erzeugen?

Antwort

3

Es ist in:

list[int] d <- GetDivisors(i) 

, wenn Sie durchlaufen die Ergebnisse GetDivisors Sie bekommen int 's nicht, list[int]' s. Es sollte also gut genug sein, das auf int d oder nur d (Typ Rückschluss) zu ändern.

Sie könnte auch dies tun:

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

Dies bindet die d Variable auf das Ergebnis der GetDivisors

Aber für diesen Fall würde ich es wie folgt schreiben:

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

Dieser letzte Ausdruck ist genau richtig! –

4

Die Wurzel Ihres Problems ist list[int] d <- GetDivisors(i). Da GetDivisorslist[int] zurückgibt, sind seine Elemente vom Typ int.

Also die erste Lösung ist: int d <- GetDivisors(i).

Aber jetzt müssen Sie auch den Typ div in lrel[int,int] div beheben.

Das komplette Beispiel wird dann:

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

Ein Hinweis auf Stil: wir normalerweise Funktionsnamen lassen mit einem Kleinbuchstaben beginnen.

+2

Ich wollte wirklich, dass der lrel den Typ [int, list [int]] hat. Tupel von int und list [int]. Und für Sie Stil Bemerkung: Ich werde versuchen, es besser zu machen :). Ich verbringe die meiste Zeit in C#, also kommen diese Konventionen natürlich. –

Verwandte Themen