我正在创建一个小于或等于4,000,000的斐波那契数列中所有偶数的列表。在Haskell中,我将斐波那契数列定义为:

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]),但是那里也没有运气。

我正在努力了解到底发生了什么以及如何最好地解决该问题。

最佳答案

sum [ x | x <- take 50 fibs, x `mod` 2 == 0, last x <= 4*10^6 ]



take 50 fibsInteger[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个元素。

关于haskell - 无法将预期类型“[Integer]”与实际类型“Integer”匹配,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42742594/

10-16 02:36