1) Das Problem ist, dass sqrt
den Typ (Floating a) => a -> a
hat, aber Sie versuchen, eine Ganzzahl als Argument zu verwenden. Sie müssen also Ihre Integer zuerst in eine Floating-Datei konvertieren, z.von sqrt (fromIntegral x)
2 schreiben) sehe ich keinen Grund, warum == sollte nicht faul sein, aber für den Test für eine leere Sammlung können Sie die null
Funktion verwenden (was definitiv faul ist, wie es auf unendlichen Listen funktioniert):
isPrime :: Integer->Bool
isPrime x = null [y | y<-[2..floor (sqrt (fromIntegral x))], x `mod` y == 0]
Um jedoch eine idiomatische Lösung zu erhalten, sollte das Problem in kleinere Teilprobleme zerlegt werden. Zuerst müssen wir eine Liste aller Elemente y mit y * y < = x:
takeWhile (\y -> y*y <= x) [2..]
Dann müssen wir die Elemente nur die x teilen:
filter (\y -> x `mod`y == 0) (takeWhile (\y -> y*y <= x) [2..])
Dann müssen wir, wenn diese Liste überprüfen leer ist:
isPrime x = null (filter (\y -> x `mod`y == 0) (takeWhile (\y -> y*y <= x) [2..]))
Und wenn Ihnen das lispy aussieht, mit $
isPrime x = null $ filter (\y -> x `mod` y == 0) $ takeWhile (\y -> y*y <= x) [2..]
0 einige der Pars ersetzen
Für zusätzliche Klarheit können Sie "auslagern", um die Lambda-Ausdrücke:
isPrime x = null $ filter divisible $ takeWhile notTooBig [2..] where
divisible y = x `mod`y == 0
notTooBig y = y*y <= x
Sie können es machen fast "human readable" von null $ Filterwechsel mit jeder nicht $:
isPrime x = not $ any divisible $ takeWhile notTooBig [2..] where
divisible y = x `mod`y == 0
notTooBig y = y*y <= x
Letzte Deklaration funktioniert für alle Zahlen, die größer oder gleich 2 sind. Für 1 wird fälschlicherweise als Primzahl angegeben, da 1 keine Primzahl ist. – Elmex80s