我正在努力创建斐波纳契系列中所有偶数的列表,这些数字小于或等于4,000,000。在Haskell中,我将Fibonacci系列定义为:
fibs = 1 : 2 : next fibs
where
next (a : t@(b:_)) = (a+b) : next t
并使用以下列表理解来构建我的集合:
[ x | x <- take 50 fibs, x `mod` 2 == 0, last x <= 4*10^6 ]
然而,GHC引发Couldn't match expected type ‘[Integer]’ with actual type ‘Integer’
错误。
我理解谓词last x <= 4*10^6
是导致错误的原因。受Hammar的回答here的启发,我最初的反应是确保4*10^6
是正确的类型,因此我尝试将谓词重新定义为last x <= toInteger 4*10^6
无效;同样的错误。我还想过,我可能需要将4*10^6
指定为单身(即[4*10^6]
),但也没有运气。
我很难理解究竟发生了什么,以及如何最好地解决问题。
答案 0 :(得分:3)
sum [ x | x <- take 50 fibs, x `mod` 2 == 0, last x <= 4*10^6 ]
take 50 fibs
是Integer
([Integer]
)的列表,x
是该列表的元素(因此是Integer
)。 last
是一个带有列表的函数......
GHCi> :t last
last :: [a] -> a
...但是你正在传递Integer
。您不需要last
来过滤列表理解中的元素;只需使用:
sum [ x | x <- take 50 fibs, x `mod` 2 == 0, x <= 4*10^6 ]
顺便说一下,如果您知道fibs
中的数字总是增加,您可以将表达式写成:
-- (<= 4*10^6) is shorthand for (\x -> x <= 4*10^6)
sum [ x | x <- takeWhile (<= 4*10^6) fibs, x `mod` 2 == 0 ]
-- Three equivalent alternatives:
(sum . takeWhile (<= 4*10^6)) [ x | x <- fibs, x `mod` 2 == 0 ]
(sum . takeWhile (<= 4*10^6) . filter (\x -> x `mod` 2 == 0)) fibs
(sum . takeWhile (<= 4*10^6) . filter ((== 0) . (`mod` 2))) fibs
这样你就不需要50个元素的任意限制。
答案 1 :(得分:2)
fibs :: [Integer]
take 50 fibs :: [Integer]
x <- take 50 fibs
x :: Integer
last :: [a] -> a
last x :: ???
如果删除last
,您的列表理解将会出现问题。我认为你打算写的更像是
[ x | x <- takeWhile (<= 4*10^6) $ take 50 fibs, x `mod` 2 == 0 ]
虽然。