![](/img/trans.png)
[英]Couldn't match expected type [a] with actual type `Integer -> [Integer]'
[英]Couldn't match expected type ‘[Integer]’ with actual type ‘Integer’
我正在创建一个小于或等于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'
错误Couldn't match expected type '[Integer]' with actual type 'Integer'
。
我知道谓词last x <= 4*10^6
会导致错误。 受到hammar 在这里的回答的启发,我的最初反应是确保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 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个元素。
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 ]
虽然。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.