无法将预期类型'[Integer]'与实际类型'Integer'匹配

时间:2017-03-12 01:15:25

标签: haskell

我正在努力创建斐波纳契系列中所有偶数的列表,这些数字小于或等于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]),但也没有运气。

我很难理解究竟发生了什么,以及如何最好地解决问题。

2 个答案:

答案 0 :(得分:3)

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个元素的任意限制。

答案 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 ]

虽然。