2015-05-05 29 views
2

我是Haskell的新手,我正在編寫一個計算函數限制的程序。因此,考慮兩個列表ab,增量dx = 0.001和集成lr的限制,我想遞歸地計算曲線下面積與方程: a1(x)^b1 + a2(x)^b2 + ... + an(x)bn其中x是的增量lr之間所有的值各個值之間爲dx。該技術部分不是那麼重要我猜,但它有助於閱讀代碼:由於使用「區域」而沒有出現(Fractional Int)實例

import Text.Printf (printf) 

-- This function should return a list [area]. 
solve :: Int -> Int -> [Int] -> [Int] -> [Double] 
solve l r x y = [area l r x y] 

area l r a b = if (l < r) 
      then (calc l a b) * 0.001 + (area (l + 1) r a b) 
      else (calc r a b) * 0.001 


calc n (a:arest) (b:brest) = (fromIntegral(n) ^^ b) * fromIntegral(a) + (calc n arest brest) 
calc n [] [] = 0 


--Input/Output. 
main :: IO() 

main = getContents >>= mapM_ (printf "%.1f\n"). (\[a, b, [l, r]] -> solve l r a b). map (map read. words). lines 

我沒有得到任何錯誤與上面的代碼,但只要我改變area (l + 1) r a barea (l + 0.001) r a b我收到以下錯誤信息:

No instance for (Fractional Int) arising from a use of `area' 

我試着做一個新的類,有一個抽象類型,但沒有工作,任何其他的想法?

+2

嘗試向所有頂層函數添加類型簽名。例如,這也將幫助您澄清哪些參數應該是整數,哪些應該是雙倍。 – chi

回答

7

所以問題是Int不是Fractional類型。換句話說,它沒有一個值叫做0.001[注1],但你已經要求Haskell在你的代碼中給你這樣一個值。

因爲0.001被饋送到與另一參數(在這種情況下l),其是Int類型的(+)功能您正在發出此請求。這是一個問題,因爲該函數的類型爲(+) :: (Num a) => a -> a -> a:換句話說,有許多不同的函數(+)都具有a -> a -> a類型; Num類型類中的每個類型a都存在這些函數之一。

由於我們知道該函數的一個參數是Int,因此我們使用的是特定功能(+) :: Int -> Int -> Int。這就是爲什麼l + 0.001變得很奇怪。

作爲解決這個問題:你可能想lrDouble型的(他們離開,並在其中一些可能是正確的界限?),但如果你相信他們一定是Int當時的你可能打算寫fromIntegral l + 0.001。款式

邊注:在Haskell括號中始終只是分組/優先級功能優先級高於運營商,其設置優先,特殊形式(letcaseifdo)更高,功能應用上始終左結合或「貪婪的名義」:一個函數會立即吃掉它前面的任何東西。你寫什麼:

(fromIntegral(n) ^^ b) * fromIntegral(a) + (calc n arest brest) 

可能是更好的寫法如下:

fromIntegral a * fromIntegral n ^^ b + calc n arest brest 

各地calc括號是沒有必要的(因爲喜歡+運營商擁有比功能應用的優先級低),也不是周圍的括號(因爲那些子表達式是不可分割的組塊; fromIntegral(n)fromIntegral (n)相同,與fromIntegral n相同)。

  1. 由於@dfeuer在下面提到:偷偷地說,當你寫0.001它沒有確定的類型;而是在內部翻譯爲fromRational 0.001,其中後者0.001是確定類型Rational的確定值,就像當您編寫4時將其翻譯爲fromInteger 4,其中後者4是確定類型Integer的確定值。問題是Int沒有fromRational函數,因爲Int不是Fractional類型類的一部分,它定義了fromRational。它不是該類型類的一部分,因爲語言設計者傾向於對一部分進行無聲舍入/丟棄的錯誤。
+0

在我看來,「沒有'0.001'的實例」有點令人困惑。實際上,'0.001'字面意思是'fromRational 0.001'。 'fromRational :: Fractional a => Rational - > a',因此是錯誤。 – dfeuer

+0

@dfeuer謝謝,編輯它以反映這一點。 –

相關問題