How can I build a list from another list, creating multiple elements for each element in the original list? - list

I want to do something like
[(x, y, x+y) | (x,y) <- original]
But of course, this will return something like:
[(0, 0, 0), (0, 1, 1), (1, 1, 2)]
What I want is something like:
[0, 0, 0, 0, 1, 1, 1, 1, 2]
I am quite new to Haskell, and unfamiliar with its idioms. How can I accomplish this in Haskell?

First, a diatribe on types. You are drawing the pair (x,y) from a list named original. Original must be a list of pairs, original :: [(a,b)], such as [(1,6), (4,9)]. You then construct a tuple for each element, hence your result of a list of tuples. I am going by the guess that you never wanted any tuples but actually want some number of elements of the list to be combined by your function and concatenate the results into a new list.
You might looking for the concatMap function:
> :t concatMap
concatMap :: (a -> [b]) -> [a] -> [b]
> concatMap (\x -> [x,x+1,x+7]) [1,2,3]
[1,2,8,2,3,9,3,4,10]
If you actually want to consume two (or more) elements at once then there are a few missing details, such as what to do if you have an odd number of elements and weather or not elements repeat (so you see [1,2,3] as two inputs 1,2 and 2,3).
If elements repeat then this is just a concatMap and a zip:
> let ls = [1,2,3] in concatMap (\(x,y) -> [x,y,x+y]) (zip ls (drop 1 ls))
[1,2,3,2,3,5]
But if you want to see them as [1,2] and [3] then you're best off writing your own function:
func [] = []
func [x] = [[x]] -- What do you want with the odd remaining element?
func (x:y:rest) = [x,y,x+y] : func rest
> concat (func [1,2,3])
[1,2,3,3]

Looks like you're just making a non-deterministic choice -- just what list comprehensions were made for!
[v | (x,y) <- original, v <- [x, y, x+y]]

You can for example create a list of lists and then use concat to flatten it.
concat [[x, y, x+y] | (x, y) <- original]

Related

Haskell method that creates infinite list with all combinations of a given list

My Problem is that I want to create a infinite list of all combinations of a given list. So for example:
infiniteListComb [1,2] = [[],[1],[2], [1,1],[1,2],[2,1],[2,2], [1,1,1], ...].
other example:
infiniteListComb [1,2,3] = [[], [1], [2], [3], [1,1], [1,2], [1,3], [2,1],[2,2],[2,3],[3,1],[3,2],[3,3],[1,1,1], ...].
Reminds me of power sets, but with lists with same elements in it.
What I tried:
I am new in Haskell. I tried the following:
infiniteListComb: [x] -> [[x]]
infiniteListComb [] = []
infiniteListComb [(x:xs), ys] = x : infiniteListComb [xs,ys]
But that did not work because it only sumed up my list again. Has anyone another idea?
Others already provided a few basic solutions. I'll add one exploiting the Omega monad.
The Omega monad automatically handles all the interleaving among infinitely many choices. That is, it makes it so that infiniteListComb "ab" does not return ["", "a", "aa", "aaa", ...] without ever using b. Roughly, each choice is scheduled in a fair way.
import Control.Applicative
import Control.Monad.Omega
infiniteListComb :: [a] -> [[a]]
infiniteListComb xs = runOmega go
where
go = -- a combination is
pure [] -- either empty
<|> -- or
(:) <$> -- a non empty list whose head is
each xs -- an element of xs
<*> -- and whose tail is
go -- a combination
Test:
> take 10 $ infiniteListComb [1,2]
[[],[1],[1,1],[2],[1,1,1],[2,1],[1,2],[2,1,1],[1,1,1,1],[2,2]]
The main downside of Omega is that we have no real control about the order in which we get the answers. We only know that all the possible combinations are there.
We iteratively add the input list xs to a list, starting with the empty list, to get the ever growing lists of repeated xs lists, and we put each such list of 0, 1, 2, ... xs lists through sequence, concatting the resulting lists:
infiniteListComb :: [a] -> [[a]]
infiniteListComb xs = sequence =<< iterate (xs :) []
-- = concatMap sequence (iterate (xs :) [])
e.g.
> take 4 (iterate ([1,2,3] :) [])
[[],[[1,2,3]],[[1,2,3],[1,2,3]],[[1,2,3],[1,2,3],[1,2,3]]]
> sequence [[1,2,3],[1,2,3]]
[[1,1],[1,2],[1,3],[2,1],[2,2],[2,3],[3,1],[3,2],[3,3]]
> take 14 $ sequence =<< iterate ([1,2,3] :) []
[[],[1],[2],[3],[1,1],[1,2],[1,3],[2,1],[2,2],[2,3],[3,1],[3,2],[3,3],[1,1,1]]
The essence of Monad is flatMap (splicing map).
sequence is the real magician here. It is equivalent to
sequence [xs, ys, ..., zs] =
[ [x,y,...,z] | x <- xs, y <- ys, ..., z <- zs ]
or in our case
sequence [xs, xs, ..., xs] =
[ [x,y,...,z] | x <- xs, y <- xs, ..., z <- xs ]
Coincidentally, sequence . replicate n is also known as replicateM n. But we spare the repeated counting from 0 to the growing n, growing them by 1 at a time instead.
We can inline and fuse together all the definitions used here, including
concat [a,b,c...] = a ++ concat [b,c...]
to arrive at a recursive solution.
Another approach, drawing on answer by chi,
combs xs = ys where
ys = [[]] ++ weave [ map (x:) ys | x <- xs ]
weave ((x:xs):r) = x : weave (r ++ [xs])
There are many ways to implement weave.
Since list Applicative/Monad works via a cartesian-product like system, there's a short solution with replicateM:
import Control.Monad
infiniteListComb :: [x] -> [[x]]
infiniteListComb l = [0..] >>= \n -> replicateM n l

Creating a list of all possible lists, given each element can take one of n values

In Haskell I'm trying to create a function with the typing Int -> [a] -> [[a]], that generates a list such as: [[0, 0], [0, 1], [1, 0], [1, 1]] where each element in the smaller lists can take the value of either 1 or 0. Each of the smaller lists has the same size, which in this case is 2. If the size of the smaller lists was 3, I would expect to get the output [[0,0,0], [0,0,1], [0,1,0], [1,0,0], [1,1,0], [0,1,1], [1,0,1], [1,1,1]]
I've looked in to the permutations function, but this does not achieve exactly what I want. I believe there is also a variate function, but I cannot access this library.
Rather than the exact function (which would also be useful), what would be the process to generate such a list?
As oisdk mentions in a comment, a more general version of this exact function is already defined, with the name Control.Monad.replicateM:
Prelude> import Control.Monad (replicateM)
Prelude Control.Monad> replicateM 3 [0,1]
[[0,0,0],[0,0,1],[0,1,0],[0,1,1],[1,0,0],[1,0,1],[1,1,0],[1,1,1]]
We can use the list monad for this:
example :: [[Int]]
example = do
x <- [0,1]
y <- [0,1]
pure [x,y]
ghci> example
[[0,0],[0,1],[1,0],[1,1]]
Play with this. Then you should be able to combine it with recursion on n to create the function you need.
I'm not sure I understood the specification, but from the examples, one possible definition is
lists :: Int -> [[Int]]
lists 0 = [[]]
lists n = map (0:) xss ++ map (1:) xss
where xss = lists (n-1)
-- λ> lists 2
-- [[0,0],[0,1],[1,0],[1,1]]
-- λ> lists 3
-- [[0,0,0],[0,0,1],[0,1,0],[0,1,1],[1,0,0],[1,0,1],[1,1,0],[1,1,1]]
Another definition, using comprehension instead of map, is
lists :: Int -> [[Int]]
lists 0 = [[]]
lists n = [x:xs | x <- [0,1], xs <- lists (n-1)]
-- λ> lists 2
-- [[0,0],[0,1],[1,0],[1,1]]
-- λ> lists 3
-- [[0,0,0],[0,0,1],[0,1,0],[0,1,1],[1,0,0],[1,0,1],[1,1,0],[1,1,1]]
You can use the sequence function.
Like this:
λ>
λ> :t sequence
sequence :: (Traversable t, Monad m) => t (m a) -> m (t a)
λ>
λ> let { allLists :: Int -> [a] -> [[a]] ; allLists n xs = sequence $ replicate n xs ; }
λ>
λ> allLists 3 [0,1]
[[0,0,0],[0,0,1],[0,1,0],[0,1,1],[1,0,0],[1,0,1],[1,1,0],[1,1,1]]
λ>

Throwing away element in index,element tuples

New to Haskell, and trying to construct an [[(Int, Int)]] where each element is its corresponding grid position, constructed from another board [[a]]. Therefore a square [[a]] of side length 3 would create
[[(0, 0), (1, 0), (2, 0)]
,[(0, 1), (1, 1), (2, 1)]
,[(0, 2), (1, 2), (2, 2)]]
(eventually I'll be iterating over this with a map (map ...) into a function of type [[a]] -> (Int, Int) -> b to create a [[b]], so if I'm missing something massively easier, let me know!)
In Python I might do something like:
[[(x,y) for (x,_) in enumerate(board[y])] for (y,_) in enumerate(board)]
That is to say, I'd use the enumerate builtin to construct (index, element) tuples and throw away the element.
I know in Haskell I can do:
[[(x,y) | x <- [0..length (board!!y)-1]] | y <- [0..length board-1]]
but those sorts of constructions in Python (for foo in range(len(bar))) are a bit of an anti-pattern and heavily discouraged. Is that true in Haskell, as well?
If I were to write the Haskell like I'd write the Python, I'd do:
[[(x,y) | (x,_) <- zip [0..] (board!!y)] | (y,_) <- zip [0..] board]
Is that frowned upon?
Your final "write it like Python" suggestion is almost good, but you are unnecessarily throwing away the rows of the board, and then re-creating them with (!!). Writing it like this instead would be perfectly fine:
board :: [[Char]]
board = ["abc", "def", "ghi"]
board' :: [[(Int, Int)]]
board' = [[(x, y) | (x, _) <- zip [0..] row]
| (y, row) <- zip [0..] board]
Well usually the (!!) :: [a] -> Int -> a is not really a nice operator: it requires O(k) time to access the k-th element. For your small example that is of course not really an issue, but it can turn some algorithms from O(n) into O(n2).
Usually in Haskell, one aims to avoid it by writing clever algorithms that can iterate through the list, instead of obtaining a (random) index.
In Python you can rewrite your:
[[(x,y) for (x,_) in enumerate(board[y])] for (y,_) in enumerate(board)]
into:
[[(x,y) for (x,_) in enumerate(by)] for (y,by) in enumerate(board)]
and the equivalent in Haskell would be:
[ [ (x,y) | (x,_) <- zip [0..] by ] | (y,by) <- zip [0..] board ]
Or we can make the code cleaner by first introducing an enumerate :: (Enum a, Num a) => [b] -> [(a, b)] function in Haskell:
enumerate :: (Enum a, Num a) => [b] -> [(a, b)]
enumerate = zip [0..]
and then write:
[ [ (x,y) | (x,_) <- enumerate by ] | (y,by) <- enumerate board ]
Your aside seems to suggest you might be interested in the following function, sometimes called mapWithIndex (e.g., in containers) and sometimes called imap (in lens).
mapWithIndex :: (Int -> a -> b) -> [a] -> [b]
mapWithIndex f = go 0
where
go !_i [] = []
go i (x : xs) = f i x : go (i + 1) xs
So mapWithIndex (\i -> mapWithIndex (\j y -> (i,j,y))) will take a list of lists and annotate each element with its position. Of course, rather than annotating, you can perform an arbitrary calculation.

List of lists, take next element

I have [[Integer]] -> [Integer] and want to take the first element of the first sub-list, the second element of the second sub-list and .. the n-th element of the n-th sub-list and so on.
I am trying to achieve this using list comprehensions. However, I first drop an incrementing number of elements and the take the head of the remaining. But there again I don't know how to use drop (inc z) where z = 0 with inc c = c + 1 as an already defined function, in presumably this:
getNext :: [[Integer]] -> [Integer]
getNext xs = [y | drop (inc z) (y:ys) <- xs, (y:_) <- xs]
where z = 0
I know that the code above is not working, but again I had only so far come up to this and hit a wall.
You can do it like this:
getNext :: [[a]] -> [a]
getNext xs = [ head $ drop y x | (x,y) <- zip xs [0..]]
Although note that this function is partial because of head.
As the other answers suggest, you can use a zip function and zip with the list of indices.
The Glasgow Haskell Compiler (GHC) however offers the Parallel List Comp extension:
{-# LANGUAGE ParallelListComp #-}
diagonal :: [[a]] -> [a]
diagonal ls = [l !! i | l <- ls | i <- [0..]]
The (!!) operator gets the i-th element from a list.
Furthermore it is always advisable to use the most generic function signature; so [[a]] -> [a] instead of [[Integer]] -> [Integer]. This can be useful if you later decide to take the diagonal of a matrix of Double's, String, lists, custom types,...
You can zip the actual list of list of integers and another list which runs from 0 to infinity and get the corresponding elements, like this
picker :: [[Integer]] -> [Integer]
picker xs = [(x !! y) | (x, y) <- (zip xs [0..])]
main = print $ picker [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
-- [1,5,9]
The expression [0..] will create an infinite list, lazily, starting from 0 and we zip it with xs. So, on every iteration, the result of zip would be used like this
[1, 2, 3] !! 0
[4, 5, 6] !! 1
[7, 8, 9] !! 2
We get element at index 0, which is 1, on the first iteration and 5 and 9 on the following iterations.

Haskell add unique combinations of list to tuple

Say for example that I have a list like this
list = ["AC", "BA"]
I would like to add every unique combination of this list to a tuple so the result is like this:
[("AC", "AC"),("AC","BA"),("BA", "BA")]
where ("BA","AC") is excluded.
My first approach was to use a list comprehension like this:
ya = [(x,y) | x <- list, y <- list]
But I couldn't manage to get it to work, is there anyway to achieve my result by using list comprehensions?
My preferred solution uses a list comprehension
f :: [t] -> [(t, t)]
f list = [ (a,b) | theTail#(a:_) <- tails list , b <- theTail ]
I find this to be quite readable: first you choose (non-deterministically) a suffix theTail, starting with a, and then you choose (non-deterministically) an element b of the suffix. Finally, the pair (a,b) is produced, which clearly ranges over the wanted pairs.
It should also be optimally efficient: every time you demand an element from it, that is produced in constant time.
ThreeFx's answer will work, but it adds the constraint that you elements must be orderable. Instead, you can get away with functions in Prelude and Data.List to implement this more efficiently and more generically:
import Data.List (tails)
permutations2 :: [a] -> [(a, a)]
permutations2 list
= concat
$ zipWith (zip . repeat) list
$ tails list
It doesn't use list comprehensions, but it works without having to perform potentially expensive comparisons and without any constraints on what kind of values you can put through it.
To see how this works, consider that if you had the list [1, 2, 3], you'd have the groups
[(1, 1), (1, 2), (1, 3),
(2, 2), (2, 3),
(3, 3)]
This is equivalent to
[(1, [1, 2, 3]),
(2, [2, 3]),
(3, [3])]
since it doesn't contain any extra or any less information. The transformation from this form to our desired output is to map the function f (x, ys) = map (\y -> (x, y)) ys over each tuple, then concat them together. Now we just need to figure out how to get the second element of those tuples. Quite clearly, we see that all its doing is dropping successive elements off the front of the list. Luckily, this is already implemented for us by the tails function in Data.List. The first element in each of these tuples is just makes up the original list, so we know we can use a zip. Initially, you could implement this with
> concatMap (\(x, ys) -> map (\y -> (x, y)) ys) $ zip list $ tails list
But I personally prefer zips, so I'd turn the inner function into one that doesn't use lambdas more than necessary:
> concatMap (\(x, ys) -> zip (repeat x) ys) $ zip list $ tails list
And since I prefer zipWith f over map (uncurry f) . zip, I'd turn this into
> concat $ zipWith (\x ys -> zip (repeat x) ys) list $ tails list
Now, we can reduce this further:
> concat $ zipWith (\x -> zip (repeat x)) list $ tails list
> concat $ zipWith (zip . repeat) list $ tails list
thanks the eta-reduction and function composition. We could make this entirely pointfree where
> permutations2 = concat . ap (zipWith (zip . repeat)) tails
But I find this pretty hard to read and understand, so I think I'll stick with the previous version.
Just use a list comprehension:
f :: (Ord a) => [a] -> [(a, a)]
f list = [ (a, b) | a <- list, b <- list, a <= b ]
Since Haskell's String is in the Ord typeclass, which means it can be ordered, you first tell Haskell to get all possible combinations and then exclude every combination where b is greater than a which removes all "duplicate" combinations.
Example output:
> f [1,2,3,4]
[(1,1),(1,2),(1,3),(1,4),(2,2),(2,3),(2,4),(3,3),(3,4),(4,4)]