Consecutive pairs from list in haskell - list

How can I get a list of consecutive pairs (tuples) from a list without recursion ?
For example : [1, 2, 3, 4] would be [(1, 2), (2, 3), (3, 4)]

\xs -> zip xs $ tail xs or zip <*> tail.

Related

How to create all possible combinations of these two lists?

I'd like to take from these two lists to create a list of all combinations, where each combination is also a list.
E.g.
Given two lists: [1,2,3] and [True, False]
Combinations:
[(1, False), (2, False), (3, False)]
[(1, False), (2, False), (3, True )]
[(1, False), (2, True ), (3, False)]
[(1, True ), (2, False), (3, False)]
[(1, False), (2, True ), (3, True )]
[(1, True ), (2, False), (3, True )]
[(1, True ), (2, True ), (3, False)]
[(1, True ), (2, True ), (3, True )]
There should be 2^n combinations where n is the number of numbers.
EDIT:
Tried to do the following:
[(n, b) | n <- [1,2,3], b <- [True, False]]
(,) <$> [1,2,3] <*> [True, False]
We can avoid using length, which might be unsafe, since the list can have infinite length. By using recursion or a foldr pattern, we avoid that:
{-# LANGUAGE TupleSections #-}
allComb :: [b] -> [a] -> [[(a,b)]]
allComb vs = go
where go [] = [[]]
go (x:xs) = (:) <$> map (x,) vs <*> go xs
or with a foldr-pattern in a one-liner:
allComb :: [b] -> [a] -> [[(a,b)]]
allComb vs = foldr (\x -> ((:) <$> map (x,) vs <*>)) [[]]
For example:
Prelude> allComb [False, True] [1,2,3]
[[(1,False),(2,False),(3,False)],[(1,False),(2,False),(3,True)],[(1,False),(2,True),(3,False)],[(1,False),(2,True),(3,True)],[(1,True),(2,False),(3,False)],[(1,True),(2,False),(3,True)],[(1,True),(2,True),(3,False)],[(1,True),(2,True),(3,True)]]
The above approach will not work on infinite lists, although we can, given the first list contains at least one element, slightly alter the code, to generate the first element of the result: a list that zips all the elements in the second list with that item. I leave that as an exercise.
This can't be the most straightforward or most efficient answer.
But using the technique from How to generate a list of all possible strings from shortest to longest we can generate a list of all possible Boolean sequences. We take the ones that are the same length as the second list and then zip them with that list.
allBoolPermutations :: Int -> [[Bool]]
allBoolPermutations n = takeWhile (\l -> length l == n)
$ dropWhile (\l -> length l < n)
$ allBools
where
allBools = [ c : s | s <- []:allBools, c <- [True, False]]
zipWithBoolPermutations :: [a] -> [[(a, Bool)]]
zipWithBoolPermutations someList = map (zip someList)
(allBoolPermutations (length someList))
Then zipWithBoolPermutations [1,2,3] should give you what you want.
Your desired output can be produced by defining
foo :: [a] -> [b] -> [[(a, b)]]
foo nums bools =
map (zip nums) . sequence $ replicate (length nums) bools
=
let n = length nums
in
[ zip nums bs | bs <- sequence $ replicate n bools]
and calling
foo [1,2,3] [False, True]
That call is equivalent to
let nums = [1,2,3]
bools = [False, True]
n = 3
in
[ zip nums bs | bs <- sequence $ replicate n bools]
=
[ zip [1,2,3] bs | bs <- sequence $ replicate 3 [False, True]]
=
[ zip [1,2,3] (b:bs) | b <- [False, True]
, bs <- sequence $ replicate 2 [False, True]]
=
[ zip [1,2,3] (b:c:bs) | b <- [False, True]
, c <- [False, True]
, bs <- sequence $ replicate 1 [False, True]]
=
[ zip [1,2,3] (b:c:d:bs) | b <- [False, True]
, c <- [False, True]
, d <- [False, True]
, bs <- sequence $ replicate 0 [False, True] ]
=
[ zip [1,2,3] (b:c:d:bs) | b <- [False, True]
, c <- [False, True]
, d <- [False, True]
, bs <- sequence [] ]
=
[ zip [1,2,3] (b:c:d:bs) | b <- [False, True]
, c <- [False, True]
, d <- [False, True]
, bs <- [[]] ]
=
[ zip [1,2,3] (b:c:d:[]) | b <- [False, True]
, c <- [False, True]
, d <- [False, True] ]
i.e.
[ zip [1,2,3] [b,c,d] | b <- [False, True]
, c <- [False, True]
, d <- [False, True] ]
and if evaluate this last expression, we also get the same result.
Filling up the three spaces with each possible combination of the two available values is like having all possible functions from 3 spaces to 2 values, whatever those spaces and values are.
Mathematicians write this function as 23, and indeed, we get 2^3 = 8 outputs.
edit: the sequence ... replicate combo is actually just reimplementing another built-in, replicateM:
foo ns bs = map (zip ns) (replicateM (length ns) bs)
because replicateM n a is just like sequence (replicate n a), but without actually building the intermediate list.
For the pointfree aficionados, we can thus have
foo ns = map (zip ns) . replicateM (length ns)
= (.) ((map . zip) ns) ((replicateM . length) ns)
= ((.) . map . zip <*> replicateM . length) ns
i.e.
foo = (.) . map . zip <*> replicateM . length
Nice and short:
traverse ((<$> [True, False]) . (,)) [1,2,3]
Or less pointfree, but perhaps more understandable:
traverse (\x -> [(x,True), (x,False)]) [1,2,3]
The inner function ((<$> [True, False]) . (,) or \x -> [(x,True), (x,False)]) takes each element such as 1 and turns it into [(1,True),(1,False)]. If you think of traverse f as being sequence . fmap f, then the fmap f part means do that function to each thing in the list (yielding [[(1,True),(1,False)],[(2,True),(2,False)],[(3,True),(3,False)]]), and the sequence part means combine them with the List applicative (which models non-determinism) to create all possible combinations (yielding [[(1,True),(2,True),(3,True)],[(1,True),(2,True),(3,False)],[(1,True),(2,False),(3,True)],[(1,True),(2,False),(3,False)],[(1,False),(2,True),(3,True)],[(1,False),(2,True),(3,False)],[(1,False),(2,False),(3,True)],[(1,False),(2,False),(3,False)]]).

Haskell - separate a list of pairs in two lists using fold

So, I am given a list containing tuples and I need to break it down into two lists, the first list containing the elements with odd index and the second list containing the elements with even index, must be done using fold, here is my attempt:
breakList :: [(Integer, Integer)] -> [[(Integer, Integer)]]
breakList [] = [[], []]
breakList xxs#(x:xs) = foldl (\ acc y -> if length (acc !! 0) < length (acc !! 1) then y : (acc !! 0) else y : (acc !! 1) ) [[], []] xxs
Error I am getting:
Couldn't match type '(Integer, Integer)'
with '[(Integer, Integer)]'
Expected type: [[(Integer, Integer)]]
when hovering over y : (acc !! 1) and y : (acc !! 0)
Example:
Input:
ex1 = [ (2, 2), (1, 3), (2, 3), (2, 4), (3, 5), (0, 2), (2, 1), (1, 4)
, (2, 0), (1, 2), (3, 1), (1, 0)]
Output
breakList ex1
== ( [(2,2),(2,3),(3,5),(2,1),(2,0),(3,1)] , [(1,3),(2,4),(0,2),(1,4),(1,2),(1,0)])
The standard trick here, as hinted at by Willem in the comments, which I first saw few years back on SO in an (F# or Ocaml) answer by [user:Ed'ka], is
evenodds :: [a] -> ([a], [a])
evenodds xs = foldr g ([],[]) xs
where
g x ~(as,bs) = (bs,x:as)
or
oddevens :: [a] -> ([a], [a])
oddevens xs = foldr g ([],[]) xs
where
g x ~(bs,as) = (x:as,bs)
What are odd positions from here, are even positions from the position one notch further on the list.
The tilde ~ introduces a lazy pattern so that the function is properly lazy in its operations.
Note that you want to split a list into two lists of a pair, so the return type should be
([(Integer, Integer)], [(Integer, Integer)])
not
[[(Integer, Integer)]]
and access the element of pair, you can use fst and snd instead of through index, and finally, use foldl will return the resulted list in reversed order, it can be fixed use foldr instead. The correction look like:
breakList :: [(Integer, Integer)]->([(Integer, Integer)], [(Integer, Integer)])
breakList xxs = foldr (\y acc-> if length (fst acc) < length (snd acc)
then (y:(fst acc), snd acc)
else (fst acc, y:(snd acc)) ) ([], []) xxs

List multiplication with nested lists

Consider the list of lists
thisList = [[1], [1, 1], [1, 1, 1]]
how could I multiple thisList so that it would produce another list
anotherList = [[1], [2, 2], [3, 3, 3]]
I have made the function
reps = [1] : map (\ns -> head ns:ns) reps
which produces thisList
Thanks for any help
You could do:
zipWith (\x -> map (const x)) [1..] thisList
Example usage:
Prelude> let thisList = [[1], [1,1], [1,1,1]]
Prelude> zipWith (\x -> map (const x)) [1..] thisList
[[1],[2,2],[3,3,3]]
Or simpler:
zipWith (map . const) [1..] thisList
It's quite easy. zipWith f as bs is equivalent to map (uncurry f) $ zip as bs. So we have:
zip [1..] thisList == [(1, [1]), (2, [1,1,]), (3, [1,1,1])]
Then we apply f to each pair and so:
map (const 1) [1] == [const 1 1] == [1]
map (const 2) [1,1] == [const 2 1, const 2 1] == [2,2]
map (const 3) [1,1,1] == [const 3 1, const 3 1, const 3 1] == [3,3,3]
If you meant that a sublist of length n should be replaced by [n, n, ..., n] of length n, as in:
thisList = [[1, 1], [1], [1], [1, 1, 1]]
result = [[2,2], [1], [1], [3,3,3]]
then you have to change approach:
map (\xs -> let len = length xs in replicate len len) thisList
Example:
Prelude> let thisList = [[1, 1], [1], [1], [1, 1, 1]]
Prelude> map (\xs -> let len = length xs in replicate len len) thisList
[[2,2],[1],[1],[3,3,3]]

Group a list of tuples by their 1st element

Say I have a tuple list that consists of [("ab", 1), ("ab", 2), ("ac", 3)]
Using the group function would split this list into a list of lists of tuples like so:
[
[("ab", 1)],
[("ab", 2)],
[("ac", 3)]
]
How would you group the tuple ignoring one of the indices so that they'd be grouped based on one of the elements:
[
[("ab", 1), ("ab", 2)],
[("ac", 3]
]
Would the groupBy function be needed in this case?
Use Data.List groupBy function (docs):
Prelude> import Data.List
Prelude Data.List> let xs = [("ab", 1), ("ab", 2), ("ac", 3)]
Prelude Data.List> groupBy (\a b -> fst a == fst b) xs
[[("ab",1),("ab",2)],[("ac",3)]]
or as suggested by #dfeuer:
...
import Data.Function
groupBy ((==) `on` fst) xs

sml foldl explanation/trace

I'm trying to figure this out for some time but I'm not successful.
How is following function (powerset) proceeding in detail, taking the example input argument of [1,2,3]?
Thank you much for help.
fun ps L = foldl (fn (x,tl) => tl # map (fn xs => x::xs) tl) [[]] L;
To use the function correctly, you have to assume there is no duplication in input lists.
The function can be understood as follows:
We start with an accumulator which is a set of sets only consisting of an empty set ([[]]).
In each step, we take every set in the accumulator, add the current element x to them and add these results to the accumulator.
The final result is a set of all possible sets of n elements i.e. powerset.
To be easily express traces, let's create an auxiliary function f
fun f (x, tl) = tl # map (fn xs => x::xs) tl
Now we have a trace for [1, 2, 3]:
ps [1, 2, 3]
~> foldl f [[]] [1, 2, 3] (* Step 1 *)
~> foldl f (f (1, [[]])) [2, 3]
~> foldl f ([[]] # map (fn xs => 1::xs) [[]]) [2, 3]
~> foldl f [[], [1]] [2, 3] (* Step 2 *)
~> foldl f (f (2, [[], [1]])) [3]
~> foldl f ([[], [1]] # map (fn xs => 2::xs) [[], [1]]) [3]
~> foldl f [[], [1], [2], [2, 1]] [3] (* Step 3 *)
~> foldl f (f (3, [[], [1], [2], [2, 1]])) []
~> foldl f ([[], [1], [2], [2, 1]] # map (fn xs => 3::xs) [[], [1], [2], [2, 1]]) []
~> foldl f [[], [1], [2], [2, 1], [3], [3, 1], [3, 2], [3, 2, 1]] [] (* Step 4 *)
~> [[], [1], [2], [2, 1], [3], [3, 1], [3, 2], [3, 2, 1]] (* Final result *)