2015-10-13 123 views
1

我有以下代碼(與項目歐拉的問題34):爲什麼Haskell代碼失敗?

fac :: Int -> Int 
fac = foldr1 (*) . enumFromTo 1 

fe :: Int -> Bool 
fe = (==) =<< (sum . map fac . digits 10) 

fes :: [Int] 
fes = filter fe [3..] 

fac工作正常,fe工作正常,但fes給出:

*** Exception: Prelude.foldr1: empty list 

有趣的是,如果我開始的清單, 145(fe此處返回True),它適用於該數字,然後引發異常。

爲什麼此代碼失敗?它看起來像是一個完全正常的應用程序filter,它具有一個清晰的功能以及一個可以單獨使用該功能的常規數字列表。

+1

您的代碼充滿了無點不可讀性。無論如何,'fac'被調用的參數小於1,導致列表參數爲'foldr1'(非常陰暗的函數)爲空。 – dfeuer

+3

@dfeuer巴,我認爲唯一難以閱讀的部分是'(==)= <<'。 –

+1

@ØrjanJohansen我不一定會在實際的'生產'代碼中這樣寫;我做這些練習主要是爲了試驗Haskell。使用'foldr1(*)'代替'product'也是一樣的。然而,你關於'foldl'與'foldr'的觀點,以及@dfeur對'foldr1''shadiness'的觀點當然是一個好主意。如果我在這裏使用'產品',我不會遇到這個問題,但我也不會學到這些東西。 :) – Ben

回答

6

您的fac失敗,數字爲0,其列表爲空。您可以嘗試

fac = foldr (*) 1 . enumFromTo 1 

順便說foldl'(從Data.List)可能是更好的比foldr在這裏,也有一個預定義的product功能。

相關問題