2016-06-08 106 views
0

我試圖編寫一個函數,測試一個數字的平方根是否是整數。 我的函數如下:Haskell沒有實例...出現

check :: [Int] -> [Int] 
check xs = filter (\n -> n == round sqrt n) xs 

而且我收到錯誤消息是這些:

No instance for (Integral (Int -> Int)) 
(maybe you haven't applied enough arguments to a function?) 
arising from a use of "round" 
In the second argument of "(==)", namely "round sqrt n" 
... 
No instance for (Floating a0) arising from a use of `sqrt' 
The type variable `a0' is ambiguous 
Note: there are several potential instances: 
instance Floating Double -- Defined in `GHC.Float' 
instance Floating Float -- Defined in `GHC.Float' 
In the first argument of `round', namely `sqrt' 

編輯:我結束了重寫整個問題,我希望那不是問題!

+1

你想'round(sqrt n)'而不是'round sqrt n'。你還需要一個fromIntegral的右手錶達。因此'check = filter(\ n - > n == fromIntegral(round(sqrt n)))' – pdexter

+0

函數調用是不是右對應的? 此外,我仍然收到兩條錯誤消息: '沒有使用「round」引起的(RealFrac Int)實例 '沒有使用「sqrt」引發的(Floating Int)實例 – DQQpy

+0

刪除您的' [Int] - > [Int]'類型,例如,您想要'[Double] - > [Double]'。如果你真的想要'Int',那麼你必須進一步改變定義。函數調用是左關聯的。 – pdexter

回答

1

所以我發現另一種解決辦法由自己:

check :: [Int] -> [Int] 
check xs = filter (\n -> (ceiling (sqrt (fromIntegral n))) == (floor (sqrt (fromIntegral n)))) xs 

這是一個不拋出(在我的情況)編譯器錯誤唯一的一個。

2

,如果你刪除它會工作的左fromIntegral

test n = n == fromIntegral (round n) 

的原因是因爲它是你的n必須是RealFracround)和IntegralfromIntegral),但有沒有類型中拉開序幕這既是(均未Integer也不Double例如)

如果刪除了左fromIntegral只需n有一個類型這是一個實例- Double例如

右側是這樣的:

RealFrac -round-> Integral -fromIntegral-> RealFrac 

,如果你有疑問可以隨時問GHCI:

Prelude> :i RealFrac 
class (Real a, Fractional a) => RealFrac a where 
    properFraction :: Integral b => a -> (b, a) 
    truncate :: Integral b => a -> b 
    round :: Integral b => a -> b 
    ceiling :: Integral b => a -> b 
    floor :: Integral b => a -> b 
    -- Defined in ‘GHC.Real’ 
instance RealFrac Float -- Defined in ‘GHC.Float’ 
instance RealFrac Double -- Defined in ‘GHC.Float’ 

,你可以看到這種類型 - 類給你的方式 - 回數到Integral(要求Integral看看是什麼 - 提示:認爲像整數)

你也看到了實例

如果你看到RealFrac Int這意味着它正在尋找RealFrac實例定義Int(有沒有)

爲什麼有一個Int是另一回事:

  • 要麼你遇到了一個技術性:GHCI默認nInt在這裏 - 你可能遇到了可怕的monomorphism restriction - 這應該不會發生這樣的新版GHC版本,但是...
  • ,或者你使用它的情況下,它約束Int(我們沒有看到)

說實話我不知道它是在這裏

+0

沒有第一個fromIntegral也不行。 編輯:但這是否意味着來自整合只是像下面的約束?我認爲它就像是一個轉換器函數 – DQQpy

+0

也是的,它是一個Int因爲上下文;) – DQQpy

+0

很明顯,它是相當無用的,首先是一個'Int'(一個'Int'總是*整數*) - 但在這種情況下,它會像'test n = n == round(fromInteral n)' - 你使用'fromIntegral'去到一些'RealFrac',然後你可以使用'round'返回 - 但記住:這實際上是無用的 – Carsten

2

應該

check :: [Int] -> [Int] 
check xs = filter (\n -> fromIntegral n == round (sqrt (fromIntegral n))) xs 

錯誤消息告訴你的問題:

(maybe you haven't applied enough arguments to a function?) 
arising from a use of "round" 

因爲round sqrt n調用round與論據sqrtn

但這仍然沒有做你想要的。您需要sqrt對方以及

check :: [Int] -> [Int] 
check xs = filter (\n -> sqrt (fromIntegral n) == round (sqrt (fromIntegral n))) xs 
+0

哦,當然也有另一面...我現在肯定太累了,所以我明天會試試,非常感謝! – DQQpy

+0

仍然錯誤:'歧義類型變量「A0」的約束: (浮動A0) 從使用「SQRT」 (積分A0) 從而產生一個使用「fromIntegral」 (民A0) 產生所產生從使用「fromIntegral」' 你們有一個鏈接或什麼東西,我可以瞭解所有這些關於數字類型類的東西?我找不到任何新手友好和信息與谷歌。 – DQQpy