reset password
Author Message
cgaldam2
Posts: 9
Posted 18:13 Oct 26, 2016 |

The following was in the Haskell book: map (\l@(x:xs) -> (x,length l)) . group . sort $ [1,1,1,1,2,2,2,2,3,3,2,2,2,5,6,7]

What does ' l@(x:xs) ' do? I tried looking for another example like that but I could not find it.

ejaan
Posts: 27
Posted 21:50 Oct 26, 2016 |

let me try to explain it, Please profressor Abbot correct my answer if I am not getting right  ^_^

- - - - - - - - - - - - - - - - - - - - - - - - - - 

Prelude Data.List> map (\l@(x:xs) -> (x,length l)) . group . sort $ [1,1,1,1,2,2,2,2,3,3,2,2,2,5,6,7]

I think that  l@(x:xs)

does the matching part of the code when the pattern is matching.

- - - - - - - - - - - - - - - - - - - - - - - - - - 

map (\l@(x:xs) -> (x,length l))

is a function that takes a list of lists and returns a list of tuples  map (\l@(x:xs) -> (x,length l)) :: [[a]] -> [(a, Int)]

and I am guessing that it works by matching the pattern so it matches when the pattern matches

the first part of the code group . sort $ [1,1,1,1,2,2,2,2,3,3,2,2,2,5,6,7] results which is [[1,1,1,1],[2,2,2,2,2,2,2],[3,3],[5],[6],[7]]

group takes a list and groups adjacent elements into sublists if they are equal.

by maping the result the group to the function and match the pattern we get a list of tuples as a result [(1,4),(2,7),(3,2),(5,1),(6,1),(7,1)]

I am guessing that it works as the following example : 

 l@(x:xs)  ----> 1 @ ( 1: the rest of the list) 

-> (x,length l))   -----> ( 1 , length [1] )  -- and the length returns te number of items in a lis​​​t​​​​

the result of the first tulpe will be (1, 4) 

- - - - - - - - - - - - - - - - - - - - - - - - - - 

Prelude Data.List> map (\l@(x:xs) -> (x,length l)) [[1,1,1,1],[2,2,2,2,2,2,2],[3,3],[5],[6],[7]]

[(1,4),(2,7),(3,2),(5,1),(6,1),(7,1)]

 

 

Last edited by ejaan at 21:50 Oct 26, 2016.
rabbott
Posts: 1649
Posted 22:33 Oct 26, 2016 |

The answer above is basically right--although "l" matches the entire list, not just the 1.  Good work!

Here's a quick summary.

The form a@pattern as a function parameter (whether the function is named or not) means that a refers to the entire pattern.

So

\list@(x:xs) -> (x,length list)

is a lambda function that expects a list as its argument. 

  • x matches the head.
  • xs matches the tail.
  • list matches the entire list. (I used list instead of l because l is confusing.)

For example:

> (\list@(x:xs) -> (list, x, xs)) [1, 2, 3, 4]
([1,2,3,4],1,[2,3,4])

 

It's basically a convenience to let you match pieces of a data structure and the entire structure at the same time.

Last edited by rabbott at 08:21 Oct 27, 2016.
cgaldam2
Posts: 9
Posted 09:02 Oct 27, 2016 |

Thank you for the clarification makes sense now.