BeanieBarrow
BeanieBarrow

Reputation: 162

Couldn't match expected type ‘Bool’ with actual type ‘a -> Bool’

I want to write a function that returns the longest prefix of a list, where applying a function to every item in that prefix produces a strictly ascending list.

For example:

longestAscendingPrefix (`mod` 5) [1..10] == [1,2,3,4]

longestAscendingPrefix odd [1,4,2,6,8,9,3,2,1] == [1]

longestAscendingPrefix :: Ord b => (a -> b) -> [a] -> [a]
longestAscendingPrefix _ [] = []
longestAscendingPrefix f (x:xs) = takeWhile (\y z -> f y <= f z) (x:xs)

This code snippet produces the error message in the title. It seems the problem lies within that lambda function.

Upvotes: 4

Views: 366

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476604

takeWhile has type takeWhile :: (a -> Bool) -> [a] -> [a]. The first parameter is thus a function that maps an element of the list to a Bool. Your lambda expression has type Ord b => a -> a -> Bool, which does not make much sense.

You can work with explicit recursion with:

longestAscendingPrefix :: Ord b => (a -> b) -> [a] -> [a]
longestAscendingPrefix f = go
    where go [] = []
          go [x] = …
          go (x1:x2:xs) = …

where you need to fill in the parts the last one makes a recursive call to go.

Upvotes: 5

Related Questions