How do I read names in Haskell? - list

I just encountered this example on learnyouahaskell.com. However, I don't understand it at all.
ghci> let xxs = [[1,3,5,2,3,1,2,4,5],[1,2,3,4,5,6,7,8,9],[1,2,4,2,1,6,3,1,3,2,3,6]]
ghci> [ [ x | x <- xs, even x ] | xs <- xxs]
[[2,2,4],[2,4,6,8],[2,4,2,6,2,6]] -- This is the output
My problem is that while I do understand the idea of list comprehensions, I don't get what the xxs means.
If it was just the name of the list of lists, how can we split up a name and do something like xs <- xxs. To me that doesn't make sense at all.
Can someone help?

xxs is the list of lists bound in the let expression. I think you're being confused by the similarity of xxs and xs, they are just two independent names with no relation. You can replace xs with sublist or any other valid name.
ghci> let xxs = [[1,3,5,2,3,1,2,4,5],[1,2,3,4,5,6,7,8,9],[1,2,4,2,1,6,3,1,3,2,3,6]]
ghci> [ [ x | x <- sublist, even x ] | sublist <- xxs]
So we're not splitting on the name we're just using the <- list comprehension operator to iterate over the elements of a [[a]] and then have another comprehension for iterating over the elements of each [a] sublist.

Related

Haskell Function to multiply elements in a list

dobb[] = []
dobb (x:xs) = [x * 2| x<- xs]
I am really new to haskell and started learning it this week. I want to create a function that multiplies each element in a list by 2. So the list would go from [1,2,3] to [2,4,6]. The code I have works fine, except it skips the first element of the list and goes from [1,2,3] to [4,6]. How can I make the code multiply the first element as well?
[x*2 | x<-[1..5]]
I've found this line that does what I am looking for, but I dont understand how to go from this line of code and convert it to a function that works for all lists.
I'll address your last question,
how to go from this line of code,
[x*2 | x <- [1..5]]
and convert it to a function that works for all lists[?]
This is known as generalization and is achieved by abstraction. First we name it,
foo = [x*2 | x <- [1..5]]
then we name that arbitrary piece of data we used as an example to work on,
foo = let {xs = [1..5]} in [x*2 | x <- xs]
and then we abstract over it by removing that arbitrary piece of data in the internal definition, letting it become the function parameter instead, to be specified by this, now, function's callers:
foo xs = [x*2 | x <- xs]
and there it is, the general function working on all lists, doing the same thing as it did on the specific example we used at first.
If you use the pattern (x:xs) then you unpack the list such that x is the head (first item) of the list, and xs is the tail (remaining items) of that list. For a list [1,4,2,5], x will thus refer to 1, and xs to [4,2,5].
In the list comprehension, you then use x <- xs as a generator, and thus you enumerate over the remaining elements. The x in the list comprehension is furthermore not the head of the list, but a more locally scoped variable.
You can work with list comprehension and work on the entire list, so:
dobb :: Num a => [a] -> [a]
dobb xs = [x * 2| x <- xs]
We can also work with map :: (a -> b) -> [a] -> [b] to perform the same operation on the elements:
dobb :: Num a => [a] -> [a]
dobb = map (2*)

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

How to display the list but without a certain item.

I have the following list, that contains a list of strings..
I have already searched the orginal list for the lists that contain the string "tom" and got the following list
[["leo", "tom"], ["meg", "tom"], ["George", "john", "adam", "tom"] ]
I now wish to display this list without "tom", i would do this through list comprehension but i don't know how to do that for a list that contains lists? Can someone help me into the right direction?
Writing this as a list comprehension would get complicated, I think. Easier to just chain simple functions.
-- Intended as l `without` x
without :: Eq a => [a] -> a -> [a]
without l x = filter (/= x) l
containing :: Eq a => [[a]] -> a -> [[a]]
containing l x = filter (x `elem`) l
listsWithTom = lists `containing` "tom"
listsMinusTom = map (`without` "tom") listsWithTom
notom xss = [[ x | x <- xs, x /= "tom"] | xs <- xss]
Or
notom = map (filter (/= "tom"))
Or in your particular case
notom = map init

Help on a list manipulating list

Hi I am a newbie in Haskell.
I am trying to do a simple task.
test :: (RealFloat a) => a -> a -> [a]
test xs ys= [ w : h: [] | w <- xs, h <- ys]
I am getting an error here. (with out a doubt)
In this task, I am simply trying to bind two lists (ex: test [12.12] [14.14])
and hopefully return a new combined list (ex: [12.12,14.14])
thanks for your help
Your signature is wrong. Try:
test xs ys = ...
then in ghci:
> :t test
test :: [t] -> [t] -> [[t]]
You need two arguments, both are lists, not two arguments of single elements.
Drakosha is correct. List concatenation already has an operator in Haskell.
test :: (RealFloat a) => [a] -> [a] -> [a]
test xs ys= xs ++ ys
You probably don't want to use a list comprehension here, unless you want to extract every element in your first and second list and do something with them. For example, a Cartesian Product:
list1 = [1.0,1.1,1.2] :: [Double]
list2 = [2.0,2.1,2.2] :: [Double]
testComps xs ys = [(x,y) | x <- xs, y <- ys]
Or addition:
testComps2 xs ys = [ x + y | x <- xs, y <- ys]
Or even creating lists:
testComps3 xs ys = [x : y : [] | x <- xs, y <- ys]
In GHCi, this will yield the following:
*Main> testComps list1 list2
[(1.0,2.0),(1.0,2.1),(1.0,2.2),(1.1,2.0),(1.1,2.1),(1.1,2.2),(1.2,2.0),(1.2,2.1)
,(1.2,2.2)]
*Main> testComps2 list1 list2
[3.0,3.1,3.2,3.1,3.2,3.3000000000000003,3.2,3.3,3.4000000000000004]
*Main> testComps3 list1 list2
[[1.0,2.0],[1.0,2.1],[1.0,2.2],[1.1,2.0],[1.1,2.1],[1.1,2.2],[1.2,2.0],[1.2,2.1]
,[1.2,2.2]]
The weird results in testComps2 is, of course, normal cruft when you're dealing with floating-point numbers. In the real world you'd compensate for this by rounding.
Another problem you'll run into is the difference between (++) and (:). Simply put, (:) tacks individual items onto a list, whereas (++) concatenates two lists.
You need list concatenation:
[12.12] ++ [14.14]
=> [12.12,14.14]

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 :-)