Haskell prime test
Ich bin neu in Haskell, und ich versuche ein bisschen:
isPrime :: Integer->Bool
isPrime x = ([] == [y | y<-[2..floor (sqrt x)], mod x y == 0])
Habe ich ein paar Fragen.
- Warum, wenn ich versuche zu laden .hs, WinHugs sagen: Instanzen
(Floating Integer, RealFrac Integer)
erforderlich für die definition derisPrime
? - Wenn der interpreter findet ein element in der rechten Menge, ist es sofort beendet wird oder berechnet er alle gesetzt? Ich denke, du weißt, was ich meine.
Sorry für mein Englisch.
Du musst angemeldet sein, um einen Kommentar abzugeben.
1) Das problem ist, dass
sqrt
hat der Typ(Floating a) => a -> a
, aber Sie versuchen, verwenden eine ganze Zahl als argument. So müssen Sie konvertieren Sie Ihre ganze Zahl zunächst in eine Schwebende, z.B. durch das schreiben vonsqrt (fromIntegral x)
2) ich sehe keinen Grund, warum == sollte nicht faul sein, aber zum testen für eine leere Auflistung können Sie die
null
- Funktion (die ist definitiv faul, wie es funktioniert auf unendliche Listen):Aber um mehr idiomatische Lösung, brechen das problem in kleinere sub-Probleme. Zuerst brauchen wir eine Liste aller Elemente y mit y*y <= x:
Dann brauchen wir nur noch die Elemente, die teilen x:
Dann müssen wir überprüfen, dass die Liste leer ist:
Und wenn dieser sieht lispy, um Sie, tauschen Sie die Klammern mit $
Für zusätzliche übersichtlichkeit können Sie "outsourcen" der lambdas:
Können Sie machen es fast "human-readable" durch das ersetzen null $ filter mit nicht $ alle:
Weil
sqrt
hat der TypFloating a => a -> a
. Dies bedeutet, dass der Eingang hat eineFloating
Art und der Ausgang der gleiche Typ. In anderen Wortenx
mussFloating
geben. Aber Sie erklärtx
TypInteger
, das ist nicht einFloating
geben. Zusätzlichfloor
braucht eineRealFrac
geben, sox
werden muss, dass auch.Die Fehlermeldung deutet darauf hin, dass Sie beheben, indem
Integer
eineFloating
- Typ (durch Definition einer InstanzFloating Integer
(und das gleiche fürRealFrac
).Dies ist natürlich nicht der richtige Ansatz in diesem Fall. Vielmehr sollten Sie verwenden
fromIntegral
zu konvertierenx
zu einemReal
(das ist eine Instanz vonFloating
undRealFrac
) und dann gebensqrt
.Ja. Sobald
==
sieht, dass der Rechte operand besitzt mindestens ein element, es weiß ist nicht gleich[]
und damit zurückFalse
.Dass gesagt wird, die
null
ist mehr idiomatische Weg, um zu überprüfen, ob eine Liste leer ist, als[] ==
.truncate . sqrt . fromIntegral
für keine. 1 undall (\y -> x `mod` y /= 0) [...]
.Bezug auf den zweiten Punkt, es hört auf, zum Beispiel:
Zurück
False
[x | x <- [1..]]
ist das gleiche wie[1..]
btw.Landei ' s Lösung ist Super, allerdings, wenn Sie wollen eine mehr efficient1 Umsetzung haben wir (Dank BMeph):
Der "Effizienz" kommt von der Verwendung von Konstanten Primzahlen. Es verbessert die Suche in zwei Richtungen:
beachten Sie, dass die
sieve
Wert ist einfach nur eine rekursive Tabelle, wo sagt der Leiter desdie Liste ist eine Primzahl, und fügt es zu. Für den rest der Listen, wenn es keine
anderen Wert bereits in der Liste, die komponiert die Nummer dann auch prime
possible
ist die Liste mit allen möglichen Primzahlen, da alle möglichen Primzahlen sind in derform 6*k-1 oder 6*k-1, außer 2 und 3
Die gleiche Regel gilt für
shortCircuit
zu schnell aus der Patsche helfen, der BerechnungenFußnote von D. F.
1 Es ist immer noch eine furchtbar ineffiziente Methode zum finden von Primzahlen. Nicht verwenden, trial division, wenn Sie brauchen Primzahlen, die größer als ein paar tausend, verwenden Sie ein Sieb, statt. Es gibt mehrere weit mehr effiziente Implementierungen auf hackage.
primes
ist quadratisch in der Anzahl der Primzahlen produziert. Die theoretische Zeit, die Komplexität des Sieb des Eratosthenes istO(n*log n*log (log n))
imn
Primzahlen produziert. Die theoretische Komplexität von trial-division istO(n^1.5/(log n)^0.5)
. Warum dann dieser code scheint einfach genug, trial division, führt das viel schlimmer? Das ist, weil das feuern der jeder filter muss verschoben, bis der prime square ist zu sehen in input-stream. Die Verdünnung der input-stream, um ein Drittel reduziert mit dem Konstanten Faktor nichts mehr.isPrime 32
dann wird es träge berechnen Sie den Ausdruck.PS: Eure isPrime ist die Umsetzung nicht die beste Umsetzung!
Instances of (Floating Integer, RealFrac Integer) required for definition of isPrime
", ähnlich wie WinHugs, sagte. 2) ja, und...? Das ist so irrelevant, ich bin mir nicht sicher, wie Sie zu Antworten; Erstens, fixieren Sie die definition so es funktioniert, dann sorgen darüber, wie es zu benutzen. PS) OP isPrime Umsetzung ist nicht die beste, gut es ist ein "er" implementiert! Helfen, erklären, wie das zu beheben sein, schreiben Ihre eigenen", oder GTFO!"