Related
I have a 2d list l, and
[l!!y!!x| x<-[0..length l-1], y<-[0..length l-1]]
will produce a 1d list where rows and columns are swapped.
How can I implement this without list comprehension(i.e. using map)?
Break down the problem into parts. To transpose a single row, you want to return a column where each row contains a single element. A 1 x n matrix becomes an n x 1 matrix:
{- 1 2 ... n 1
2
...
n
-}
transpose [row] = map (\ x -> [x]) row
E.g.: transpose [[1, 2, 3]] = [[1], [2], [3]].
\ x -> [x] can also be written as an operator section (: []) or pure from Applicative.
When you pattern-match on the outer list (input rows), you split the top row of the matrix from the remaining rows. The transpose of a matrix is the transposition of the first row prepended to the transposition of the remaining rows. You can join two matrices vertically (i.e. placing one atop the other) with (++) (which could be written as (<>) from Semigroup) or horizontally with zipWith (++) (resp. zipWith (<>)) (i.e. placing one beside the other). Transposed matrices are joined horizontally:
{- 1 2 ... n 1 a ... p
a b ... c 2 b ... q
....... .........
p q ... r n c ... r
-}
transpose (top : down)
= zipWith (++) (transpose [top]) (transpose down)
E.g.: transpose [[1, 2], [3, 4], [5, 6]] = [[1] ++ [3, 5], [2] ++ [4, 6]].
This can also be expressed as zipWith (:) top (transpose down) since we know we have single elements to prepend; this skips some of the redundant effort of wrapping and then immediately unwrapping the elements of the input row / output column.
Finally, the transposition of an empty matrix with no rows is also the empty matrix.
transpose [] = []
Putting these together:
transpose :: [[a]] -> [[a]]
transpose [r] = map (: []) r
transpose (r : rs) = zipWith (:) r (transpose rs)
transpose [] = []
Follow-up: consider how this code responds to the edge cases where the input is non-rectangular or has an infinite number of rows or columns.
As Will Ness’s answer makes clear, this recursive function is nearly equivalent to a right fold, where the combining function is the prepending of columns by zipWith (:), and the base accumulator is the empty column of indefinite height, repeat [], i.e. transpose m = foldr (zipWith (:)) (repeat []) m, or eta-reduced, transpose = foldr (zipWith (:)) (repeat []).
However, they differ in an edge case: the fold produces an infinite list when given an empty input. That version is also equivalent to getZipList . traverse ZipList, based on the observation that traverse id :: (Traversable t, Applicative f) => t (f b) -> f (t b) is a kind of generalised transposition.
Since you wanted it without explicit recursion,
zipWith is also a binary map of sorts (and in some other languages map actually can take any number of argument lists). Hence,
transposed = foldr (zipWith (:)) (repeat [])
Trying it:
> transposed [[1,2,3],[11,12,13],[21,22,23,24]]
[[1,11,21],[2,12,22],[3,13,23]]
This can be simply composed with concat :: [[a]] -> [a] to concatenate the transposed lists.
We can work with recursion for this: each time we yield the heads of the lists, and then recurse on the tails, so:
catTranspose :: [[a]] -> [a]
catTranspose ([]:_) = []
catTranspose xs = map head xs ++ …
where I leave filling in … as an exercise. It should make a recursive call where we map each item in xs to its tail.
If the list is rectangular, this will work, for non-rectangular 2d lists, you will need to work with functions that are more safe, and thus will not error like head does on an empty list.
One can also drop the explicit recursion and work for example with unfoldr :: (b -> Maybe (a, b)) -> b -> [a] and concat :: Foldable f => f [a] -> [a] that will then perform the recursion.
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
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]]
λ>
I want to perform an arithmetic operation (e.g. doubling the value) on a list of integers, every n places.
For example, given the list [1,2,3,4,5,6,7], I want to double values every three places. In that case, we would have [1,2,6,4,5,12,7].
How can I do it?
applyEvery :: Int -> (a -> a) -> [a] -> [a]
applyEvery n f = zipWith ($) (cycle (replicate (n-1) id ++ [f]))
The cycle subexpression builds a list of functions [id,id,...,id,f] with the correct number of elements and repeats it ad nauseam, while the zipWith ($) applies that list of functions to the argument list.
Since you asked for it, more detail! Feel free to ask for more explanation.
The main idea is maybe best explained with an ASCII picture (which won't stop me from writing a thousand a lot of ASCII words!):
functions : [ id, id, f , id, id, f , id, id, f, ...
input list: [ 1, 2, 3, 4, 5, 6, 7 ]
-----------------------------------------------------
result : [ 1, 2, f 3, 4, 5, f 6, 7 ]
Just like there's no reason to hardcode the fact that you want to double every third element in the list, there's nothing special about f (which in your example is doubling), except that it should have the same result type as doing nothing. So I made these the parameters of my function. It's even not important that you operate on a list of numbers, so the function works on lists of a, as long as it's given an 'interval' and an operation. That gives us the type signature applyEvery :: Int -> (a -> a) -> [a] -> [a]. I put the input list last, because then a partial application like doubleEveryThird = applyEvery 3 (*2) is something that returns a new list, a so-called combinator. I picked the order of the other two arguments basically at random :-)
To build the list of functions, we first assemble the basic building block, consisting of n-1 ids, followed by an f as follows: replicate (n-1) id ++ [f]. replicate m x makes a list containing m repetitions of the xargument, e.g. replicate 5 'a' = "aaaaa", but it also works for functions. We have to append the f wrapped in a list of its own, instead of using : because you can only prepend single elements at the front - Haskell's lists are singly-linked.
Next, we keep on repeating the basic building block with cycle (not repeat as I first had mistakenly). cycle has type [a] -> [a] so the result is a list of "the same level of nested-ness". Example cycle [1,2,3] evaluates to [1,2,3,1,2,3,1,2,3,...]
[ Side note: the only repeat-y function we haven't used is repeat itself: that forms an infinite list consisting of its argument ]
With that out of the way, the slightly tricky zipWith ($) part. You might already know the plain zip function, which takes two lists and puts elements in the same place in a tuple in the result, terminating when either list runs out of elements. Pictorially:
xs : [ a , b , c , d, e]
ys: [ x, y , z ]
------------------------------
zip xs ys: [(a,x),(b,y),(c,z)]
This already looks an awful lot like the first picture, right? The only thing is that we don't want to put the individual elements together in a tuple, but apply the first element (which is a function) to the second instead. Zipping with a custom combining function is done with zipWith. Another picture (the last one, I promise!):
xs : [ a , b , c , d, e]
ys: [ x, y, z ]
----------------------------------------
zipWith f xs ys: [ f a x, f b y, f c z ]
Now, what should we choose to zipWith with? Well, we want to apply the first argument to the second, so (\f x -> f x) should do the trick. If lambdas make you uncomfortable, you can also define a top-level function apply f x = f x and use that instead. However, this already a standard operator in the Prelude, namely $! Since you can't use a infix operator as a standalone function, we have to use the syntactic sugar ($) (which really just means (\f x -> f $ x))
Putting all of the above together, we get:
applyEvery :: Int -> (a -> a) -> [a] -> [a]
applyEvery n f xs = zipWith ($) (cycle (replicate (n-1) id ++ [f])) xs
But we can get rid of the xs at the end, leading to the definition I gave.
A common way to get indexes for values in a list is to zip the list into tuples of (value, index).
ghci > let zipped = zip [1,2,3,4,5,6,7] [1..]
ghci > zipped
[(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7)]
Then you just need to map over that list and return a new one. If index is divisible by 3 (index `rem` 3 == 0), we'll double the value, otherwise we'll return the same value:
ghci > map (\(value, index) -> if index `rem` 3 == 0 then value*2 else value) zipped
[1,2,6,4,5,12,7]
Tell me if that all makes sense—I can add more detail if you aren't familiar with zip and map and such.
Zip
You can find documentation on zip by looking at its Haddocks, which say: "zip takes two lists and returns a list of corresponding pairs." (Docs are hosted in several places, but I went to https://www.stackage.org and searched for zip).
Map
The map function applies a function to each item in a list, generating a new value for each element.
Lambdas
Lambdas are just functions without a specific name. We used one in the first argument to map to say what we should do to each element in the list. You may have seen these in other languages like Python, Ruby, or Swift.
This is the syntax for lambdas:
(\arg1, arg2 -> functionBodyHere)
We could have also written it without a lambda:
ghci > let myCalculation (value, index) = if index `rem` 3 == 0 then value*2 else value
ghci > map myCalculation zipped
[1,2,6,4,5,12,7]
Note: this code is not yet tested.
In lens land, this is called a Traversal. Control.Lens gives you these:
{-# LANGUAGE RankNTypes, ScopedTypeVariables #-}
type Traversal s t a b =
forall f . Applicative f => (a -> f b) -> s -> f t
type Traversal' s a = Traversal s s a a
We can use lens's itraverse from Control.Lens.Indexed:
-- everyNth :: (TraversableWithIndex i t, Integral i)
=> i -> Traversal' (t a) a
everyNth :: (TraversableWithIndex i t, Integral i, Applicative f)
=> i -> (a -> f a) -> t a -> f (t a)
everyNth n f = itraverse f where
g i x | i `rem` n == n - 1 = f x
| otherwise = pure x
This can be specialized to your specific purpose:
import Data.Profunctor.Unsafe
import Data.Functor.Identity
everyNthPureList :: Int -> (a -> a) -> [a] -> [a]
everyNthPureList n f = runIdentity #. everyNth n (Identity #. f)
mapIf :: (Int -> Bool) -> (a -> a) -> [a] -> [a]
mapIf pred f l = map (\(value,index) -> if (pred index) then f value else value) $ zip l [1..]
mapEveryN :: Int -> (a -> a) -> [a] -> [a]
mapEveryN n = mapIf (\x -> x `mod` n == 0)
Live on Ideone.
A simple recursive approach:
everyNth n f xs = igo n xs where
igo 1 (y:ys) = f y : igo n ys
igo m (y:ys) = y : igo (m-1) ys
igo _ [] = []
doubleEveryThird = everyNth 3 (*2)
Basically, igo starts at n, counts down until it reaches 1, where it will apply the function, and go back up to n. doubleEveryThird is partially applied: everyNth expects three arguments, but we only gave it two, so dougleEveryThird will expect that final argument.
How can I flatten a nested list like this:
[1, 2, 3, 4] == flatten [[[1,2],[3]],[[4]]]
Yes, it’s concat from the Standard Prelude, given by
concat :: [[a]] -> [a]
concat xss = foldr (++) [] xss
If you want to turn [[[a]]] into [a], you must use it twice:
Prelude> (concat . concat) [[[1,2],[3]],[[4]]]
[1,2,3,4]
Since nobody else has given this, it is possible to define a function which will flatten lists of an arbitrary depth by using MultiParamTypeClasses. I haven't actually found it useful, but hopefully it could be considered an interesting hack. I got the idea from Oleg's polyvariadic function implementation.
{-# LANGUAGE MultiParamTypeClasses, OverlappingInstances, FlexibleInstances #-}
module Flatten where
class Flatten i o where
flatten :: [i] -> [o]
instance Flatten a a where
flatten = id
instance Flatten i o => Flatten [i] o where
flatten = concatMap flatten
Now if you load it and run in ghci:
*Flatten> let g = [1..5]
*Flatten> flatten g :: [Integer]
[1,2,3,4,5]
*Flatten> let h = [[1,2,3],[4,5]]
*Flatten> flatten h :: [Integer]
[1,2,3,4,5]
*Flatten> let i = [[[1,2],[3]],[],[[4,5],[6]]]
*Flatten> :t i
i :: [[[Integer]]]
*Flatten> flatten i :: [Integer]
[1,2,3,4,5,6]
Note that it's usually necessary to provide the result type annotation, because otherwise ghc can't figure out where to stop recursively applying the flatten class method. If you use a function with a monomorphic type that's sufficient however.
*Flatten> :t sum
sum :: Num a => [a] -> a
*Flatten> sum $ flatten g
<interactive>:1:7:
No instance for (Flatten Integer a0)
arising from a use of `flatten'
Possible fix: add an instance declaration for (Flatten Integer a0)
In the second argument of `($)', namely `flatten g'
In the expression: sum $ flatten g
In an equation for `it': it = sum $ flatten g
*Flatten> let sumInt = sum :: [Integer] -> Integer
*Flatten> sumInt $ flatten g
15
*Flatten> sumInt $ flatten h
15
As others have pointed out, concat :: [[a]] -> [a] is the function you are looking for, and it can't flatten nested lists of arbitrary depth. You need to call it multiple times to flatten it down to the desired level.
The operation does generalize to other monads, though. It is then known as join, and has the type Monad m => m (m a) -> m a.
Prelude Control.Monad> join [[1, 2], [3, 4]]
[1,2,3,4]
Prelude Control.Monad> join (Just (Just 3))
Just 3
Prelude Control.Monad.Reader> join (+) 21
42
import Data.List
let flatten = intercalate []
flatten $ flatten [[[1,2],[3]],[[4]]]
[1,2,3,4]
As hammar pointed out, join is the "monadic" way to flatten a list. You can use the do-Notation as well to write easily flatten functions of several levels:
flatten xsss = do xss <- xsss
xs <- xss
x <- xs
return x
An arbitrarily nested list can be approximated by a Data.Tree, which can be flattened by the appropriately named function flatten.
I say approximated because Data.Tree allows a data item to be attached to every node, not just the leaves. However, you could create a Data.Tree (Maybe a), and attach Nothing to the body nodes, and flatten with catMaybes . flatten.
You can remove one level of nesting using concat, and consequently you can apply n levels of nesting by applying concat n times.
It is not possible to write a function which removes an arbitrary level of nestings, as it is not possible to express the type of a function, which takes an arbitrarily nested list and returns a flat list, using Haskell's type system (using the list datatype that is - you can write your own datatype for arbitrarily nested lists and write a flatten function for that).