我正在嘗試使用Haskell解決Project Euler上的第二個問題。這個問題相當簡單 - 將平均斐波納契數字加起來小於4000000.(我是強迫症,我在暗示一個稍微修改過的函數 - 一個允許任意限制的函數)。Haskell無法構造無限類型:a0 = [a0]
我最初的代碼爲:
euler2 limit (num1:num2)
|(num1>limit) = 0
|((num2>limit) && ((mod num1 2) == 0)) = num1
|(num2>limit) = 0
|(((mod num1 2) == 0) && ((mod num2 2) == 0)) = num1+num2+(euler2 limit [num1+num2,num1+num2+num2])
|((mod num1 2) == 0) = num1+(euler2 limit [num1+num2,num1+num2+num2])
|((mod num2 2) == 0) = num2+(euler2 limit [num1+num2,num1+num2+num2])
|otherwise = euler2 limit [num1+num2,num1+num2+num2]
euler2 limit [] = euler2 limit [1,2]
這將產生以下錯誤:
Occurs check: cannot construct the infinite type: a0 = [a0]
In the second argument of `(>)', namely `limit'
In the first argument of `(&&)', namely `(num2 > limit)'
In the expression: ((num2 > limit) && ((mod num1 2) == 0))
現在通過一些試驗和錯誤,我已經意識到,它正試圖強制轉換num2
作爲一個列表,和這個小小的變化:
euler2 limit (num1:num2:[]) | (num1 > limit) = 0
修復了這個問題。我的問題是爲什麼?發生了什麼,爲什麼它拒絕將num1
和num2
作爲Ints?
嘗試添加一個明確的類型簽名到你的euler2函數中:'euler2 :: Integer [Integer]'(或類似的東西......)。修復類型可能會導致更簡單的錯誤消息。 – hugomg 2013-02-08 19:54:05
'num1'是一個'Int',你的問題是'num2'不是;它是'Ints'的列表。 – sabauma 2013-02-08 19:56:26
對,但明確指出:[]感覺像髒兮兮的黑客。有什麼辦法可以更優雅地執行這種事情嗎?什麼是「Haskell方式」? – 2013-02-08 19:58:58