Haskell >> operator with two lists - list

For a college assignment I am learning Haskell and when reading about the do-notation and sequencing with >>= and >> I came across this behaviour that I did not expect.
[1,2,3] >> [1] -- returns [1,1,1]
Can anyone explain why every element of the first array is replaced by the elements of the second array? It seems like the list is concatenated in some way, while I expected the result of the first expression to be completely ignored, thus I would expect [1] as the result.
Thanks a lot in advance.

The “result” is in this case the values contained in [1,2,3], which are indeed ignored. What >> does not ignore is the context, which for the list monad is the shape (i.e. length) of the list. This can't be ignored, because we must have x >>= pure ≡ x, i.e.
Prelude> [1,2,3] >>= pure
[1,2,3]
Prelude> [1,2,3] >>= \n -> [n]
[1,2,3]
Prelude> [1,2,3] >>= \n -> [1]
[1,1,1]
Prelude> [1,2,3] >>= \_ -> [1]
[1,1,1]
Prelude> [1,2,3] >> [1]
[1,1,1]
An example with length>1 on the RHS:
[1,2,3] >>= \n -> [n, n+10]
[1,11,2,12,3,13]
Prelude> [1,2,3] >>= \n -> [100, 10]
[100,10,100,10,100,10]
Prelude> [1,2,3] >> [100, 10]
[100,10,100,10,100,10]

There are several equivalent ways of writing [1,2,3] >> [1]:
do [1,2,3]
return 1
[ x | _ <- [1,2,3], x <- [1] ]
[ 1 | _ <- [1,2,3] ]
[1,2,3] >>= \_ -> [1]
concatMap (const [1]) [1,2,3]
concat (map (const [1]) [1,2,3])
concat ([1,2,3] $> [1])
It replaces every element of [1..3] with [1] and then collapses it:
concatMap (\_ -> [1]) [1,2,3]
= concat (map (\_ -> [1]) [1,2,3])
= concat [[1],[1],[1]]
= [1,1,1]
It completely ignores the elements of [1,2,3], just using the shape (length). Look what happens if we replace them with undefined:
> do [undefined, undefined, undefined]; return 1
[1,1,1]

The results of the first computation are indeed ignored.
Monads can be seen as generalized nested loops. What you have can be written in pseudocode as
for y in [1,2,3]:
for x in [1]: -- for x in ((\_ -> [1]) y):
yield x
Both y and x are in scope at the innermost level. y's value is indeed ignored.
Still for each y in [1,2,3] each x in [1] is produced, thus defining the overall computation. For lists this means the results produced one by one by the combined computation as a whole are the results produced one by one at the innermost level. Sounds trivial, isn't it.
How exactly this is implemented is an implementational detail. Seeing the lists as data this means splicing the results of the inner computations in place, flattening the list of lists into a one-level list, appending the inner lists together. concatMap is widely known as flatMap in other languages:
[ 1, 2, 3 ]
[1] [1] [1]
-------------------
[ 1, 1, 1 ]
Related answers: Why >> duplicates right-hand side operand , Map and flatMap , How does Monad on list work? , Why list monad combines in that order? , mapM with const functions in Haskell , under the hood reason we can use nested loops in list comprehensions , Generalizing prime pairs in SICP.

Related

How to create all combination of elements of certain length by intentional lists in Haskell

I would like to ask how to create all combinations of elements of a certain length by intentional lists in Haskell? Here is the example:
Function combo is taking two arguments list of elements - xs and value - n, the goal is to create all possible combinations of elements in xs of length n by intentional lists.
For example:
combo [1,2,3] 2
should return
[[1,1],[1,2],[1,3],[2,1],[2,2],[2,3],[3,1],[3,2],[3,3]]
Thank you in advance for any help
This could be done using a combinatorics library, but can also easily be done yourself.
A small example I made:
import Data.List
permutations' _ [] = []
permutations' 0 _ = []
permutations' n xs | n > length xs = error "n can't be larger than length of input"
| otherwise = permute n xs []
permute 0 xs ys = [ys]
permute n xs ys = concatMap (\x -> foo (n-1) (x `delete` xs) (ys ++ [x])) xs
The 'magic' is happening in premute where a simple combinatorics is applied.
You start off with an empty list of solutions which is extended until the character limit n is reached. The input xs e.g. [1,2,3] is mapped, thus each character in xs is fed into the lambda function. In the lambda the x is appended to the already existing result. In the first loop ys is empty thus only x is added. In subsequent calls to permute the xs list is shrunk and ys is appended with the value that xs is shrunk with. Thus growing the result until char limit is reached and subsequently removing characters from xs to prevent duplicate entries.
A walkthrough of permute 2 [1,2,3] [] might look like this:
(\1 -> foo (2-1) [2,3] [] ++ [1])
- (\2 -> foo (1-1) [3] [1] ++ [2])
- [1,2], since we hit the first pattern where n = 0
- (\3 -> foo (1-1) [2] [1] ++ [3])
- [1,3], since we hit the first pattern where n = 0
(\2 ....
(\3 ....

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

Why can't GHC reason about some infinite lists?

This recent question got me thinking about Haskell's ability to work with infinite lists. There are plenty of other questions and answers about infinite lists on StackOverflow, and I understand why we can't have a general solution for all infinite lists, but why can't Haskell reason about some infinite lists?
Let's use the example from the first linked question:
list1 = [1..]
list2 = [x | x <- list1, x <= 4]
print list2
$ [1,2,3,4
#user2297560 writes in the comments:
Pretend you're GHCI. Your user gives you an infinite list and asks you to find all the values in that list that are less than or equal to 4. How would you go about doing it? (Keep in mind that you don't know that the list is in order.)
In this case, the user didn't give you an infinite list. GHC generated it! In fact, it generated it following it's own rules. The Haskell 2010 Standard states the following:
enumFrom :: a -> [a] -- [n..]
For the types Int and Integer, the enumeration functions have the following meaning:
The sequence enumFrom e1 is the list [e1,e1 + 1,e1 + 2,…].
In his answer to the other question, #chepner writes:
You know that the list is monotonically increasing, but Haskell does not.
The statements these users made don't seem to line up with the standard to me. Haskell created the list in an ordered fashion using a monotonic increase. Haskell should know that the list is both ordered and monotonic. So why can't it reason about this infinite list to turn [x | x <- list1, x <= 4] into takeWhile (<= 4) list1 automatically?
Theoretically, one could imagine a rewrite rule such as
{-# RULES
"filterEnumFrom" forall (n :: Int) (m :: Int).
filter (< n) (enumFrom m) = [m..(n-1)]
#-}
And that automatically would convert expressions such as filter (< 4) (enumFrom 1) to [1..3]. So it is possible. There is a glaring problem though: any variation from this exact syntactical pattern won't work. The result is that you end up defining a bunch of rules and you can longer ever be sure if they are triggering or not. If you can't rely on the rules, you eventually just don't use them. (Also, note I've specialized the rule to Ints - as was briefly posted as a comment, this may break down in subtle ways for other types.)
At the end of the day, to perform more advanced analysis, GHC would have to have some tracking information attached to lists to say how they were generated. That would either make lists less lightweight of an abstraction or mean that GHC would have some special machinery in it just for optimizing lists at compile time. Neither of these options is nice.
That said, you can always add your own tracking information by making a list type on top of lists.
data List a where
EnumFromTo :: Enum a => a -> Maybe a -> List a
Filter :: (a -> Bool) -> List a -> List a
Unstructured :: [a] -> List a
This may end up being easier to optimize.
So why can't it reason about this infinite list to turn [x | x <- list1, x <= 4] into takeWhile (<= 4) list1 automatically?
The answer isn't any more specific than "It doesn't use takeWhile because it doesn't use takeWhile". The spec says:
Translation: List comprehensions satisfy these identities, which may
be used as a translation into the kernel:
[ e | True ] = [ e ]
[ e | q ] = [ e | q, True ]
[ e | b, Q ] = if b then [ e | Q ] else []
[ e | p <- l, Q ] = let ok p = [ e | Q ]
ok _ = []
in concatMap ok l
[ e | let decls, Q ] = let decls in [ e | Q ]
That is, the meaning of a list comprehension is given by translation into a simpler language with if-expressions, let-bindings, and calls to concatMap. We can figure out the meaning of your example by translating it through the following steps:
[x | x <- [1..], x <= 4]
-- apply rule 4 --
let ok x = [ x | x <= 4 ]
ok _ = []
in concatMap ok [1..]
-- eliminate unreachable clause in ok --
let ok x = [ x | x <= 4 ]
in concatMap ok [1..]
-- apply rule 2 --
let ok x = [ x | x <= 4, True ]
in concatMap ok [1..]
-- apply rule 3 --
let ok x = if x <= 4 then [ x | True ] else []
in concatMap ok [1..]
-- apply rule 1 --
let ok x = if x <= 4 then [ x ] else []
in concatMap ok [1..]
-- inline ok --
concatMap (\x -> if x <= 4 then [ x ] else []) [1..]

Haskell:: how to compare/extract/add each element between lists

I'm trying to get each element from list of lists.
For example, [1,2,3,4] [1,2,3,4]
I need to create a list which is [1+1, 2+2, 3+3, 4+4]
list can be anything. "abcd" "defg" => ["ad","be","cf","dg"]
The thing is that two list can have different length so I can't use zip.
That's one thing and the other thing is comparing.
I need to compare [1,2,3,4] with [1,2,3,4,5,6,7,8]. First list can be longer than the second list, second list might be longer than the first list.
So, if I compare [1,2,3,4] with [1,2,3,4,5,6,7,8], the result should be [5,6,7,8]. Whatever that first list doesn't have, but the second list has, need to be output.
I also CAN NOT USE ANY RECURSIVE FUNCTION. I can only import Data.Char
The thing is that two list can have different length so I can't use zip.
And what should the result be in this case?
CAN NOT USE ANY RECURSIVE FUNCTION
Then it's impossible. There is going to be recursion somewhere, either in the library functions you use (as in other answers), or in functions you write yourself. I suspect you are misunderstanding your task.
For your first question, you can use zipWith:
zipWith f [a1, a2, ...] [b1, b2, ...] == [f a1 b1, f a2 b2, ...]
like, as in your example,
Prelude> zipWith (+) [1 .. 4] [1 .. 4]
[2,4,6,8]
I'm not sure what you need to have in case of lists with different lengths. Standard zip and zipWith just ignore elements from the longer one which don't have a pair. You could leave them unchanged, and write your own analog of zipWith, but it would be something like zipWithRest :: (a -> a -> a) -> [a] -> [a] -> [a] which contradicts to the types of your second example with strings.
For the second, you can use list comprehensions:
Prelude> [e | e <- [1 .. 8], e `notElem` [1 .. 4]]
[5,6,7,8]
It would be O(nm) slow, though.
For your second question (if I'm reading it correctly), a simple filter or list comprehension would suffice:
uniques a b = filter (not . flip elem a) b
I believe you can solve this using a combination of concat and nub http://www.haskell.org/ghc/docs/6.12.1/html/libraries/base-4.2.0.0/Data-List.html#v%3anub which will remove all duplicates ...
nub (concat [[0,1,2,3], [1,2,3,4]])
you will need to remove unique elements from the first list before doing this. ie 0
(using the same functions)
Padding then zipping
You suggested in a comment the examples:
[1,2,3,4] [1,2,3] => [1+1, 2+2, 3+3, 4+0]
"abcd" "abc" => ["aa","bb","cc"," d"]
We can solve those sorts of problems by padding the list with a default value:
padZipWith :: a -> (a -> a -> b) -> [a] -> [a] -> [b]
padZipWith def op xs ys = zipWith op xs' ys' where
maxlen = max (length xs) (length ys)
xs' = take maxlen (xs ++ repeat def)
ys' = take maxlen (ys ++ repeat def)
so for example:
ghci> padZipWith 0 (+) [4,3] [10,100,1000,10000]
[14,103,1000,10000]
ghci> padZipWith ' ' (\x y -> [x,y]) "Hi" "Hello"
["HH","ie"," l"," l"," o"]
(You could rewrite padZipWith to have two separate defaults, one for each list, so you could allow the two lists to have different types, but that doesn't sound super useful.)
General going beyond the common length
For your first question about zipping beyond common length:
How about splitting your lists into an initial segment both have and a tail that only one of them has, using splitAt :: Int -> [a] -> ([a], [a]) from Data.List:
bits xs ys = (frontxs,frontys,backxs,backys) where
(frontxs,backxs) = splitAt (length ys) xs
(frontys,backys) = splitAt (length xs) ys
Example:
ghci> bits "Hello Mum" "Hi everyone else"
("Hello Mum","Hi everyo","","ne else")
You could use that various ways:
larger xs ys = let (frontxs,frontys,backxs,backys) = bits xs ys in
zipWith (\x y -> if x > y then x else y) frontxs frontys ++ backxs ++ backys
needlesslyComplicatedCmpLen xs ys = let (_,_,backxs,backys) = bits xs ys in
if null backxs && null backys then EQ
else if null backxs then LT else GT
-- better written as compare (length xs) (length ys)
so
ghci> larger "Hello Mum" "Hi everyone else"
"Hillveryone else"
ghci> needlesslyComplicatedCmpLen "Hello Mum" "Hi everyone else"
LT
but once you've got the hang of splitAt, take, takeWhile, drop etc, I doubt you'll need to write an auxiliary function like bits.

Apply "permutations" of a function over a list

Creating the permutations of a list or set is simple enough. I need to apply a function to each element of all subsets of all elements in a list, in the order in which they occur. For instance:
apply f [x,y] = { [x,y], [f x, y], [x, f y], [f x, f y] }
The code I have is a monstrous pipeline or expensive computations, and I'm not sure how to proceed, or if it's correct. I'm sure there must be a better way to accomplish this task - perhaps in the list monad - but I'm not sure. This is my code:
apply :: Ord a => (a -> Maybe a) -> [a] -> Set [a]
apply p xs = let box = take (length xs + 1) . map (take $ length xs) in
(Set.fromList . map (catMaybes . zipWith (flip ($)) xs) . concatMap permutations
. box . map (flip (++) (repeat Just)) . flip iterate []) ((:) p)
The general idea was:
(1) make the list
[[], [f], [f,f], [f,f,f], ... ]
(2) map (++ repeat Just) over the list to obtain
[[Just, Just, Just, Just, ... ],
[f , Just, Just, Just, ... ],
[f , f , Just, Just, ... ],
... ]
(3) find all permutations of each list in (2) shaved to the length of the input list
(4) apply the permuted lists to the original list, garnering all possible applications
of the function f to each (possibly empty) subset of the original list, preserving
the original order.
I'm sure there's a better way to do it, though. I just don't know it. This way is expensive, messy, and rather prone to error. The Justs are there because of the intended application.
To do this, you can leverage the fact that lists represent non-deterministic values when using applicatives and monads. It then becomes as simple as:
apply f = mapM (\x -> [x, f x])
It basically reads as follows: "Map each item in a list to itself and the result of applying f to it. Finally, return a list of all the possible combinations of these two values across the whole list."
If I understand your problem correctly, it's best not to describe it in terms of permutations. Rather, it's closer to generating powersets.
powerset (x:xs) = let pxs = powerset xs in pxs ++ map (x :) pxs
powerset [] = [[]]
Each time you add another member to the head of the list, the powerset doubles in size. The second half of the powerset is exactly like the first, but with x included.
For your problem, the choice is not whether to include or exclude x, but whether to apply or not apply f.
powersetapp f (x:xs) = let pxs = powersetapp f xs in map (x:) pxs ++ map (f x:) pxs
powersetapp f [] = [[]]
This does what your "apply" function does, modulo making a Set out of the result.
Paul's and Heatsink's answers are good, but error out when you try to run them on infinite lists.
Here's a different method that works on both infinite and finite lists:
apply _ [] = [ [] ]
apply f (x:xs) = (x:ys):(x':ys):(double yss)
where x' = f x
(ys:yss) = apply f xs
double [] = []
double (ys:yss) = (x:ys):(x':ys):(double yss)
This works as expected - though you'll note it produces a different order to the permutations than Paul's and Heatsink's
ghci> -- on an infinite list
ghci> map (take 4) $ take 16 $ apply (+1) [0,0..]
[[0,0,0,0],[1,0,0,0],[0,1,0,0],[1,1,0,0],[0,0,1,0],...,[1,1,1,1]]
ghci> -- on a finite list
ghci> apply (+1) [0,0,0,0]
[[0,0,0,0],[1,0,0,0],[0,1,0,0],[1,1,0,0],[0,0,1,0],...,[1,1,1,1]]
Here is an alternative phrasing of rampion's infinite-input-handling solution:
-- sequence a list of nonempty lists
sequenceList :: [[a]] -> [[a]]
sequenceList [] = [[]]
sequenceList (m:ms) = do
xs <- nonempty (sequenceList ms)
x <- nonempty m
return (x:xs)
where
nonempty ~(x:xs) = x:xs
Then we can define apply in Paul's idiomatic style:
apply f = sequenceList . map (\x -> [x, f x])
Contrast sequenceList with the usual definition of sequence:
sequence :: (Monad m) => [m a] -> m [a]
sequence [] = [[]]
sequence (m:ms) = do
x <- m
xs <- sequence ms
return (x:xs)
The order of binding is reversed in sequenceList so that the variations of the first element are the "inner loop", i.e. we vary the head faster than the tail. Varying the end of an infinite list is a waste of time.
The other key change is nonempty, the promise that we won't bind an empty list. If any of the inputs were empty, or if the result of the recursive call to sequenceList were ever empty, then we would be forced to return an empty list. We can't tell in advance whether any of inputs is empty (because there are infinitely many of them to check), so the only way for this function to output anything at all is to promise that they won't be.
Anyway, this is fun subtle stuff. Don't stress about it on your first day :-)