2015-10-13 155 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功能。

相关问题