`` 我是 Haskell 新手,我正在定義一個函式,給定一個 Int n,它通過搜索 mod nm ==0 的 2<=m<=sqrt(n) 來判斷一個數字是否為素數這樣的 m 存在,則 n 不是素數,如果不存在則 n 是素數。我正在嘗試定義一個數字 m 介于 2 和 sqrt n 之間的串列,即 mod nm ==0 我的想法是,如果串列為空,則 n 是素數,它不是,n 不是素數`
isprime' :: Int -> Bool
isprime' n | l == [] = True
| otherwise = False
where
l = [x|x<-[2.. sqrt n], mod n x == 0]
`
但是當我運行我的代碼并且我無法理解它時,sqrt n 似乎存在問題。有人可以解釋我做錯了什么/要更改我的代碼運行/以及為什么會出現錯誤?
uj5u.com熱心網友回復:
運行代碼會出現以下錯誤
test.hs:9:28: error:
? No instance for (Floating Int) arising from a use of ‘sqrt’
? In the expression: sqrt n
In the expression: [2 .. sqrt n]
In a stmt of a list comprehension: x <- [2 .. sqrt n]
|
9 | l = [x|x<-[2.. sqrt n], mod n x == 0]
| ^^^^^^
你說的錯誤是正確的sqrt,但其余的對于一個新的 Haskell 開發人員來說是非常不透明的。讓我們通過檢查的型別sqrt來試試看是否有幫助。
Prelude> :t sqrt
sqrt :: Floating a => a -> a
在這里,我使用ghci互動式撰寫代碼。:t詢問前面運算式的型別。該行sqrt :: Floating a => a -> a說sqrt接受一些浮點數a并回傳相同型別的東西。
類似于我們的錯誤資訊,我們看到了這個Floating 東西。這個東西是一個型別類,但為了解決這個問題,我們將把理解這些留到以后。從本質上講,haskell 試圖告訴您這不是預期Int的浮點數。我們可以通過將我們的變成 a with whichsqrt來修正這一點,這是一個將數字型別相互轉換的非常通用的函式。(請參閱從 Haskell 中的 Int 獲取 sqrt)IntFloatfromIntegral
isprime' :: Int -> Bool
isprime' n | l == [] = True
| otherwise = False
where
asFloat :: Float -- new! - tell fromIntegral we want a float
asFloat = fromIntegral n -- new! turn n into a Float
l = [x|x<-[2..sqrt asFloat], mod n x == 0]
這也是錯誤!但它是一個新的!
test.hs:10:48: error:
? Couldn't match expected type ‘Int’ with actual type ‘Float’
? In the second argument of ‘mod’, namely ‘x’
In the first argument of ‘(==)’, namely ‘mod n x’
In the expression: mod n x == 0
|
10 | l = [x|x<-[2..sqrt asFloat], mod n x == 0]
| ^
這就是說 x 突然變成 a Float。當我們更改為時,[2..sqrt asFloat]我們現在已經制作了一個Floats ( [Float]) 串列。我們需要將其改回[Int]. 我們可以通過呼叫floor平方根的結果來做到這一點。
isprime' :: Int -> Bool
isprime' n | l == [] = True
| otherwise = False
where
asFloat :: Float
asFloat = fromIntegral n
l = [x|x<-[2..floor (sqrt asFloat)], mod n x == 0] -- new! I added floor here to change the result of sqrt from a `Float` into a `Int`
現在可以正確編譯。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/528529.html
標籤:哈斯克尔
