2012-03-16 27 views
5

vardır. Bu yüzden Problem 31 üzerinde çalışıyorum. Bir sayının asal olup olmadığını belirlemek için umuduyla aşağıdaki işlevi yazdım`(y * y) <x 'işlevi iki bağımsız değişkene uygulanır, ancak' Bool 'türünde hiçbiri

:

isPrime :: Integer -> Bool 

isPrime x = prime x 2 
      where 
      prime :: Integer -> Integer -> Bool 
      prime x y | ((y*y) < x) and ((x `mod` y) /= 0) = prime x (y+1) 
         | ((y*y) >= x) = True 
         | otherwise = False 

Benim mantık bir isPrime işlevi yapmak ve 2 parametreleri, saklamak için prime denilen isPrime içinde bir işlevi vardır oldu numara asal olup olmadığını kontrol etmek istiyorum (x) ve x'in altındaki tüm sayıları kontrol etmek için bir yineleyici ve x'u bölüp bölmediklerini görün. Bu çizgi söylemek gerekiyordu

| ((y*y) < x) and ((x `mod` y) == 0) = prime x (y+1) 

: prime 3 korumaları var ben x (((y*y) < x)) karekökü daha az sayıda geçirilir ve kontrol ise x bölünebilir ise y (((x mod y) /= 0)) Eğer değilse, yinelemeyi ve daha yüksek bir sayı ile tekrar kontrol etmek için y'yi kullanırım.

Bu hat:

| ((y*y) >= x) = True 

kare kökünün altındaki tüm sayılar zaten x bölmek yoksa gibi olmak mı gerekiyor x asal olmalıdır.

Son olarak, bu satır:

| otherwise = False 

o asal değildir bu yüzden bir numara bir yerlerde bir x sayısı bölünmüş demektir.

Yazdığım kodun mantıklı olduğunu düşündüm, en verimli olduğunu biliyorum, sqrt x'in altındaki tüm sayıları kontrol edemediğimi düşündüğümden, ancak her neyse, sqrt x'in altındaki sayıları kontrol edemem, deyim:

((y*y) < x) 

GHCi diyor ki:

The function `(y * y) < x' is applied to two arguments, but its type `Bool' has none 

Ben < iki bağımsız değişken almak ve bir Bool, hata mesajı gerçekten benim için bir anlam ifade etmiyor dönmek gerekiyordu düşündüm. Neyi yanlış yaptığımı öğrenmeme yardım edebilir misin? Teşekkürler.

Ben çalıştırmak lazım şimdi Hızlı düzenleme, bu hat:

| ((y*y) >= x) = True 

olmalıdır:

| ((y*y) > x) = True 

cevap

10

Burada neler olduğunu açıklamak için ...

((y*y) < x) and ((x `mod` y) /= 0) 

Ne kaçırdığını and etrafında backticks geçerli:: Sorun bu bütün ifadeyle var, < ile değil

((y*y) < x) `and` ((x `mod` y) /= 0) 

böyle bir işlev infix kullanın eğer o bir operatör değil (örn. ++ gibi sembollerden yapılmış), o zaman onu backticks ile çevrelemeniz gerekir. hata mesajını açıklamak Şimdi

and ((y*y) < x) ((x `mod` y) /= 0) 

:

Alternatif olarak, böyle bir fonksiyonu olarak bunu dışı infix kullanabilirsiniz. Derleyicinin söylediği şey, ((y*y) < x) ifadesini bir işlev olarak kullanmaya çalıştığınızdır. Haskell'deki işlev uygulaması köşeli parantezleri kullanmıyor olduğundan, f x y gibi her şeyve y iki bağımsız değişkenine uygulanan bir f işlevidir. Eğer argümanları and ve ((x `mod` y) /= 0) işlevi ((y*y) < x) uygulamak için çalışıyoruz olarak

Eğer and etrafında komutu ters tırnak koymayı unutmuş beri Haskell ((y*y) < x) and ((x `mod` y) /= 0) yorumlar. Tabii ki, bu işe yaramıyor, çünkü ((y*y) < x) bir işlev olmayan Bool döndürüyor, bu nedenle "(y * y) < x işlevi iki bağımsız değişkene uygulanır, ancak türü Bool'un hiçbiri yok" ifadesinden şikayet ediyor. Bool bir işlev türü değildir ve dolayısıyla hiçbir argümanı yoktur. [Bool] -> Bool tip and etti - Elbette

...

, artık var başka hata da && değil and olması gerektiğidir.

+2

Urgh. Backtick'lerin backtick'lere nasıl ekleneceğini bilen var mı? Onları kaçışa benzemiyorum. – porges

+7

'&&', “mantıksal” ve “Bool -> Bool -> Bool” türünde bir işlevdir. '' '' [Bool] -> Bool' türünde benzer bir işlevdir, bu yüzden etrafındaki backtickleri buraya koymaya yardımcı olmaz. – Ben

+0

@Porges: Sizin için düzeltildi. Bildiğim kadarıyla, içeride ters eğik çizgiden kaçan backtraflarla '...' kullanmanız gerekiyor. –

10

Sana && yerine and kullanmak anlamına düşünüyorum. Bunu yaptıktan sonra herhangi bir hata olmadan yüklenir.

+0

Tanrının annesi şimdi koşuyor. Kafamı neden işe yaramadığını anladım, bana bir şey vermediğine şaşırdım ve 'tanındı ya da böyle bir şey değil. Oh, yan notu algoritmamda küçük bir hata yaptım: '| ((y * y)> = x) = Doğru 'olmalıdır: '| ((y * y)> x) = Doğru ' – Dair

+1

@anon: 've' ayrıca bir işlevdir, ancak başka bir şey yapar. – porges

+2

@anon: 've' tanındı - sadece bir infix operatörü değil. 've' bir liste alan ve bu listedeki tüm öğelerin 'True' olup olmadığını döndüren bir işlevdir. Haskell'in yapmaya çalıştığınız şey, 've' işlevinin bir argümanı ile' (y * y) icktoofay

İlgili konular