2016-06-04 17 views
3

Beim Versuch, this challenge zu lösen, stolperte ich über etwas, das ich selbst nicht erklären konnte.Tupel aus unendlicher Liste erstellen

Zuerst habe ich erzeugen eine unendliche Liste von Primzahlen wie folgt:

primes = [n|n<-[2..],product[1..n-1]`rem`n==n-1] 

Dies hat den abgeleiteten Typ [Integer] so Int-Überlauf sollte kein Problem sein.

Dann versuche ich 2-Tupel von aufeinanderfolgenden Primzahlen zu machen (Ziel: [(2,3),(5,7),...]). Um dies zu erreichen Ich schrieb eine andere Funktion:

listtotuples l=[ (l!!i, l!!(i+1)) |i<-[0,2..]] 

Seltsamer diese listtotuples Funktion scheint zum Beispiel gut zu funktionieren [0..], aber es funktioniert einfach nicht mehr, wenn ich es zu primes gelten, ist der Ausgang nur (nach Unterbrechung)

[(2,3),(5,7),(11,13),(Interrupted. 

Ich verstehe nicht, warum dies geschieht, kann jemand erklären?

EDIT: Dies geschieht nicht nur beim Versuch, die unendliche Liste auszugeben, sondern auch z. Verwenden Sie take 10 $ listtotuples primes in Prelude nach dem Laden einer Datei mit den beiden Zeilen von oben. Es bleibt genau am selben Punkt stecken.

Ich verwende Windows 7 mit GHCi 7.10.2.

EDIT2: Der vollständige Inhalt meiner Datei ist wie folgt:

order p m=head[n-1|n<-[0..],mod m (p^n)>0] 
primes = [n|n<-[2..],product[1..n-1]`rem`n==n-1] 
listtotuples l=[ (l!!i, l!!(i+1)) |i<-[0,2..]] 
p=listtotuples primes 
f n=product[r^(order s n) * s^(order r n)|(r,s)<-take n p] 

Das Problem verschwindet, sobald ich einen Kommentar/die letzte Zeile (die Funktion entfernen f, aber ich denke immer noch, dies ist sehr seltsam, wie f nicht genannt wird, und alles, was todo mit den Funktionen nicht über hat. auch wenn ich take n p in der Funktion f mit [(2,3)] allem ersetzen, wie definiert funktioniert.

+3

Es ist viel effizienter 'listToTuples xs @ (_ zu schreiben: xs') = zip xs xs'' BTW – Bakuriu

+1

: Ich habe Ihr Problem nicht reproduzieren kann:' Prelude> nehmen $ 10 listToTuples Primzahlen [(2,3), (5,7), (11,13), (17,19), (23,29), (31,37), (41,43), (47,53), (59,61), (67,71)] '(mit Ihrer Implementierung für' listToTuples'). – Bakuriu

+0

@Bakuriu Vielen Dank für den Hinweis (ich bin natürlich noch ein Anfänger). Auf meinem Computer bleibt es sogar an genau dem gleichen Punkt hängen, selbst wenn "10 $ listToTuples Primes" verwendet wird. Welche OS/Version verwenden Sie? – flawr

Antwort

6

die Zugabe von f zwingt Ihre Primzahlen, den Typ Int zu haben, der während der faktoriellen Operation überläuft. Die Argumentation geht so:

  1. take :: Int -> [a] -> [a]
  2. In f n, die Verwendung von take n p Kräfte n :: Int.
  3. Da die Argumente order den gleichen Typ haben müssen, erzwingen die Aufrufe order r n und r, s :: Int.
  4. (r, s) <- take n p Kräfte p :: [(Int, Int)]
  5. p = listtotuples primes Kräfte primes :: [Int]

Einfache Updates enthalten Bruch Schritte 2 oder 3 oben; verwenden take (fromInteger n) p Schritt 2 oder order s (fromIntegral n) und order r (fromIntegral n) zu brechen zu brechen Schritt 3.

... und jetzt wissen Sie, warum Top-Level-Typ Signaturen Hinzufügen eines Best Practice angesehen wird.=)

+0

Vielen Dank Ihre Antwort (und Ihre Geduld)! Ich habe jetzt gelernt, dass ich meine Typen mehr überprüfen sollte. (Aber Typ-Signaturen sind so verschwenderisch in * Code-Golf * =) – flawr

Verwandte Themen