Haskell Functions and Unmanaged Functions

I have the following two functions recorded.

pair :: [a] -> [(a, a)] pair [] = [] pair [x] = [] pair (x1:x2:xs) = (x1, x2) : pair xs unpair :: [(a, a)] -> [a] unpair [] = [] unpair ((x1, x2):xs) = x1 : x2 : unpair xs 

The pair will accept pairs of elements and make 2 tuples of them. If the list has an odd number of items, undo the last one. Denial is the opposite of a pair.

These work, but I wonder if there is a more concise way to write them.

+7
coding-style haskell tuples
source share
5 answers

Single line:

 pair xs = map snd . filter fst . zip (iterate not True) $ zip xs (drop 1 xs) unpair = concatMap (\(x,y) -> [x,y]) 

You could also shorten your pair definition a bit:

 pair (x1:x2:xs) = (x1, x2) : pair xs pair _ = [] 
+5
source share

This is no shorter, but for clarity, I would use splitEvery from Data.List.Split for pair :

 pair = map tuplify . filter ((>1) . length) . splitEvery 2 where tuplify [x, y] = (x, y) 

This is not in my head - it would be better to check the length of only the last list.

For unpair I would use foldr to avoid explicit recursion:

 unpair = foldr (\(x, y) -> (x:) . (y:)) [] 

It is just a matter of taste.

+4
source share

So many possibilities. How about these?

 unpair' = concatMap (\(x,y) -> [x,y]) pair' xs = map snd . filter fst . zip (cycle [True, False]) $ zip xs (tail xs) pair'' xs = [(x,y) | (True,x,y) <- zip3 (cycle [True,False]) xs (tail xs)] 

The two versions of the pair must be the same.

Edit: As for my comment above, you can use the split package from Hackage to write:

 pair xs = map head . splitEvery 2 $ zip xs (tail xs) 

which is closer to the desired

 pair xs = everyOther $ zip xs (tail xs) 

But, in a spirit of meaninglessness, I think that we probably all agree to write,

 pair = map head . splitEvery 2 . (zip <$> id <*> tail) 

to provide confusion.

+2
source share
 pair s = dropEven $ zip s (tail s) where dropEven s = map fst $ filter snd $ zip s (cycle [True, False]) unpair = concatMap (\(a, b) -> [a, b]) 

Although I definitely prefer your definition of pair .

+1
source share

This is useful for viewing templates :

 {-# LANGUAGE ViewPatterns #-} pair :: [a] -> [(a,a)] pair (splitAt 2 -> ([x,y],ys)) = (x,y) : pair ys pair _ = [] unpair :: [(a,a)] -> [a] unpair = (>>= \(x,y) -> [x,y]) 
+1
source share

All Articles