简体   繁体   中英

Couldn't match expected type ‘[Integer]’ with actual type ‘Integer’

I am working on creating a list of all the even numbers in the Fibonacci series which are less than or equal to 4,000,000. In Haskell, I've defined the Fibonacci series as:

fibs = 1 : 2 : next fibs
  where
    next (a : t@(b:_)) = (a+b) : next t

and am using the following list comprehension to construct my set:

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

However, GHC is throwing a Couldn't match expected type '[Integer]' with actual type 'Integer' error.

I understand that the predicate, last x <= 4*10^6 , is responsible for the error. Inspired by hammar's answer here , my initial reaction was to ensure that 4*10^6 was the right type, so I tried rephrasing the predicate as last x <= toInteger 4*10^6 to no avail; same error. I also thought that maybe I needed to specify 4*10^6 as a singleton (ie [4*10^6] ), but no luck there either.

I'm struggling to understand what is exactly going on and how best to resolve the issue.

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

take 50 fibs is a list of Integer ( [Integer] ), and x is an element of that list (thus an Integer ). last is a function which takes a list...

GHCi> :t last
last :: [a] -> a

... but you are passing an Integer to it. You don't need last to filter the elements in the list comprehension; just use:

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

By the way, given that you know that the numbers in fibs always increase, you can write your expression as:

-- (<= 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

That way you don't need the arbitrary limit of 50 elements.

fibs :: [Integer]
take 50 fibs :: [Integer]

x <- take 50 fibs
x :: Integer

last :: [a] -> a
last x :: ???

Your list comprehension will typecheck if you remove last . I think what you meant to write is something more like

[ x | x <- takeWhile (<= 4*10^6) $ take 50 fibs, x `mod` 2 == 0 ]

though.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM