Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pairing adjacent list items in Haskell

Tags:

list

haskell

zip

I have a chained list like

["root", "foo", "bar", "blah"]

And I'd like to convert it to a list of tuples, using adjacent pairs. Like so

[("root", "foo"), ("foo", "bar"), ("bar", "blah")]

At the moment, I'm using this to do it:

 zipAdj x = tail (zip ("":x) (x++[""]))

However, I don't really like this method. Can anyone think of a better way? If it's glaringly obvious I apologise, I'm fairly new to Haskell.

like image 712
Alex Avatar asked Dec 22 '10 03:12

Alex


People also ask

How do you check if two lists are equal in Haskell?

If your lists have always same size then just A == B . Also if your lists don't have the same size, just as == bs tells you if they are equal. @Ingo @mort's "working" solution treats, for example, [1,2,3] and [1,2,3,4] as equal, there (==) would not.

How do you get the first N elements of a list in Haskell?

There is a function in Haskell that takes first n elements of user-supplied list, named take . The syntax is: function-name arg1 arg2 . So, take takes first 1000 elements from an infinite list of numbers from 0 to infinity.


2 Answers

Okay, here's the comment as an answer:

Just zipAdj x = zip x $ tail x will suffice. zip stops upon reaching the end of the shorter of the two lists, so this simply pairs each item in the list with its successor, which seems to be all you want.

And for the sake of explaining the pointless version: zip <*> tail uses the Applicative instance for "functions from some type", which basically amounts to a lightweight inline Reader monad--in this case the list is the "environment" for the Reader. Usually this just obfuscates matters but in this case it almost makes it clearer, assuming you know to read (<*>) here as "apply both of these to a single argument, then apply the first to the second".

like image 102
C. A. McCann Avatar answered Sep 18 '22 17:09

C. A. McCann


One possible solution:

pairs [] = []
pairs (x:[]) = []
pairs (x:y:zs) = (x, y) : pairs (y : zs)

Definitely not as small as yours, and can probably be optimized quite a bit.

like image 43
Joshua Rodgers Avatar answered Sep 20 '22 17:09

Joshua Rodgers