Hook
Hook

Reputation: 391

Why do I get this error when trying to map on a list of lists?

I'm trying to use map to write a function that takes the last elements of a list of lists. For example:

 [ [0,0,4],[2,4,2],[1,3,5],[3,1,1] ] => [4,2,5,1]

I've written this:

 func l = map (last l) 

and got this error:

    > ERROR - Type error in application
 Expression     : func [[0,0,4],[2,4,2],[1,3,5],[3,1,1]]
 Term           : [[0,0,4],[2,4,2],[1,3,5],[3,1,1]]
 Type           : [[c]]
 Does not match : [a -> b]

What's the right way to do this?

Upvotes: 2

Views: 165

Answers (3)

qleguennec
qleguennec

Reputation: 544

Or even by using point free notation: f = map last

Which, in ghci, yields the type:

GHCI> let f = map last
GHCI> :t f
f :: [[b]] -> [b]
GHCI> f [ [0,0,4],[2,4,2],[1,3,5],[3,1,1] ]
[4,2,5,1]

Upvotes: 1

soulcheck
soulcheck

Reputation: 36777

Try

func l = map last l

no parenthesis.

If you take a look at the types in func [[0,0,4],[2,4,2],[1,3,5],[3,1,1] call you'll notice that since l = [[0,0,4],[2,4,2],[1,3,5],[3,1,1]], the type of l is [[c]] but then type of last l is [c] while map expects [a -> b] as it's first argument.

Upvotes: 1

Ganesh Sittampalam
Ganesh Sittampalam

Reputation: 29110

You're doing the wrong thing with last. What you are trying to do is apply it to each inner list inside the outer list l. What you're actually doing is applying it to the outer list l itself, and then map makes no sense.

You need to write map last l instead.

You can see the right form of the arguments to map from its type:

map :: (a -> b) -> [a] -> [b]

This means that map takes two arguments, one of type a -> b and another of type [a].

Note that in your code you're only giving it the first argument (last l). This is a valid thing to do in Haskell in general (look up "partial application" or "currying"), but here the first argument is supposed to be a function and last l certainly isn't.

In this case your list l is the thing of type [a], so a = [Integer] (ignoring numeric overloading). The first argument should be a function of type [Integer] -> b, and you want to use last which means that b = Integer. So the end result will be of type [Integer] as wanted.

Upvotes: 7

Related Questions