2012-03-16 32 views
5

Vì vậy, tôi đang làm việc trên Problem 31.Hàm `(y * y) <x 'được áp dụng cho hai đối số, nhưng kiểu` Bool' của nó không có

Tôi đã viết hàm sau với hy vọng để xác định xem một số là số nguyên tố:

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 

Logic của tôi là thực hiện một chức năng isPrime, và có một chức năng trong isPrime gọi prime để lưu trữ 2 thông số, các số Tôi muốn kiểm tra xem nó có phải là số nguyên tố (x) và một trình vòng lặp để kiểm tra tất cả các số dưới sqrt của x và xem liệu chúng có phân chia x hay không. prime có 3 lính gác:

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

Dòng này là nghĩa vụ phải nói: là số tôi trôi qua dưới căn bậc hai của x (((y*y) < x)) và nếu nó là kiểm tra xem x là chia hết cho y (((x mod y) /= 0)) , nếu nó không phải là tôi sử dụng đệ quy và tăng y để kiểm tra lại với một số cao hơn.

dòng này:

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

là nghĩa vụ phải được như thế nào nếu tất cả các số bên dưới căn bậc hai không chia x trong anyway, x phải nguyên tố.

Cuối cùng, dòng này:

| otherwise = False 

có nghĩa là một số ở đâu đó dọc theo dòng một số chia x vì vậy nó không là số nguyên tố.

Tôi nghĩ rằng mã tôi viết có ý nghĩa, tôi biết nó không hiệu quả nhất, xem xét tôi chỉ có thể kiểm tra số nguyên tố dưới sqrt x và không phải tất cả các số dưới sqrt x, nhưng dù sao, tôi gặp vấn đề với điều này tuyên bố:

((y*y) < x) 

GHCi nói:

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

tôi nghĩ rằng < được cho là mất trong hai đối số và trả về một Bool, thông báo lỗi không thực sự có ý nghĩa đối với tôi. Bạn có thể giúp tôi tìm ra những gì tôi đang làm sai? Cảm ơn.

chỉnh sửa nhanh bây giờ mà tôi đã nhận nó để chạy, dòng này:

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

nên là:

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

Trả lời

10

Để giải thích những gì đang xảy ra ở đây ...vấn đề không phải là với <, đó là với những biểu hiện toàn bộ:

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

gì bạn đang thiếu là backticks quanh and:

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

Khi bạn sử dụng một chức năng ghi vào như vậy, nếu nó không phải là một nhà điều hành (tức là làm bằng các biểu tượng, như ++), sau đó bạn cần phải bao quanh nó với các dấu gạch chéo ngược.

Cách khác, bạn có thể sử dụng nó không ghi vào như một chức năng, như:

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

Bây giờ để giải thích các thông báo lỗi. Trình biên dịch nói gì là bạn đang cố sử dụng biểu thức ((y*y) < x) làm hàm. Kể từ khi ứng dụng chức năng trong Haskell không sử dụng dấu ngoặc, bất cứ điều gì như f x y là một hàm f áp dụng cho hai đối số xy.

Vì bạn quên đặt backticks quanh and, Haskell dịch ((y*y) < x) and ((x `mod` y) /= 0) như bạn cố gắng áp dụng các chức năng ((y*y) < x) để các đối số and((x `mod` y) /= 0). Tất nhiên, điều này không hiệu quả, bởi vì ((y*y) < x) trả về Bool, không phải là một hàm, do đó, nó than phiền với "Hàm (y * y) < x được áp dụng cho hai đối số, nhưng loại của nó Bool không có". Bool không phải là loại chức năng và do đó không có đối số.

...

Tất nhiên, các lỗi khác mà bạn có bây giờ là nó nên && không and-and đã gõ [Bool] -> Bool.

+2

Urgh. Bất cứ ai biết làm thế nào để bao gồm backticks bên trong backticks trên SO? Tôi dường như không thể thoát khỏi chúng. – porges

+7

'&&' là hàm cho "hợp lý và", với kiểu 'Bool -> Bool -> Bool'. 'và' là một hàm tương tự với kiểu' [Bool] -> Bool', do đó, đặt các dấu backticks xung quanh nó sẽ không giúp ích gì ở đây. – Ben

+0

@Porges: Đã sửa lỗi cho bạn. Cho đến khi tôi biết, bạn cần sử dụng '... 'với các dấu gạch chéo ngược thoát ở bên trong. –

10

Tôi nghĩ bạn có nghĩa là để sử dụng chứ không phải là &&and. Sau khi làm điều đó nó tải mà không có bất kỳ lỗi nào.

+0

Mẹ của thần nó chạy ngay bây giờ. Tôi đã gãi đầu của tôi về lý do tại sao nó không hoạt động, tôi ngạc nhiên khi nó không cho tôi một cái gì đó như 'và' không được công nhận hoặc một cái gì đó như thế. Oh, bên lưu ý tôi đã thực hiện một lỗi nhỏ trong thuật toán của tôi: '| ((y * y)> = x) = True' phải là: '| ((y * y)> x) = True' – Dair

+1

@anon: 'và' cũng là một hàm, nhưng nó lại hoạt động khác. – porges

+2

@anon: 'và' được công nhận - nó chỉ là nó không phải là một nhà điều hành. 'và' là một hàm nhận danh sách và trả về xem tất cả các phần tử trong danh sách đó là' True'. Những gì Haskell nghĩ rằng bạn đang cố gắng làm là áp dụng hàm '(y * y) icktoofay

Các vấn đề liên quan