How does haskell create a new list from another list? - list

Suppose we have a list
x = [1..10]
and we intend to create another list y using this in this manner :
y= [a|a<-x]
So while creating the list y from x, it accesses each element of x( from 1 to 10) and inserts it in y in the same order. As a list in haskell is singly linked list, we can insert a new element only at its head. So first it inserts 1 to [] & we have [1]. Then it inserts 2 to its head & so we have [2,1]. Then it inserts 3 & we have [3,2,1] & so on. So ultimately we should get y as [10,9..1]. But instead we get y as [1..10]. Why is that so?

Because it "inserts" them at list's tail (while the list is being built), not head (cf. "tail recursion modulo cons"):
[a | a <- [1..10]] ==
[a | a <- (1:[2..10])] == -- [a | a <- ([1] ++ [2..10])]
1 : [a | a <- [2..10]] -- [1] ++ [a | a <- [2..10]]
This is because
[a | a <- (xs ++ ys)] == [a | a <- xs] ++ [a | a <- ys]
and
[a | a <- ys] == ys

The way you are thinking about list comprehensions is not quite correct. When you see a comprehension
y <- [f a | a <- x]
you shouldn't think about the successive result being added to the front of an (initially empty) result list.
Instead, think of each f a being added to the front of the result of running the list comprehension on the rest of x. That is,
[f a | a <- x:xs] == f x : [f a | a <- xs]
This is a recursive approach - by assuming that the result list exists for the tail of the list, you can add the next result to the front of it.

It's instructive to look at exactly how list comprehensions desugar to monadic computations, rather than use the intuition for how they work.
[a | a <- [1..3]] == do {a <- [1..3]; return a} -- desugared comprehension
== [1..3] >>= return a -- desugared do
== concat (map return [1..3]) -- definition of >>=
== concat [[1], [2], [3]] -- defintiion of return
== [1,2,3] -- definition of concat

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

Why the following two expressions have different results

fibs = 1:1:[x+y|x <- fibs, y <- tail fibs]
returns
[1,1,2,3,4,5,6,7,8,9]
fibs = 1:1:[x+y|(x, y) <- zip fibs (tail fibs)]
returns
[1,1,2,3,5,8,13,21,34,55...]
The first one is evaluating the Cartesian product (i.e. every combination) of fibs and tail fibs, while the second is evaluating the pairwise pairing.
Prelude> [(x,y) | x <- [1,2,3], y <- [4,5,6]]
[(1,4),(1,5),(1,6),(2,4),(2,5),(2,6),(3,4),(3,5),(3,6)]
Prelude> [(x,y) | (x,y) <- [1,2,3] `zip` [4,5,6]]
[(1,4),(2,5),(3,6)]

Count non-empty lists in a lists of lists

I am trying to count the number of non-empty lists in a list of lists with recursive code.
My goal is to write something simple like:
prod :: Num a => [a] -> a
prod [] = 1
prod (x:xs) = x * prod xs
I already have the deifniton and an idea for the edge condition:
nonEmptyCount :: [[a]] -> Int
nonEmptyCount [[]] = 0
I have no idea how to continue, any tips?
I think your base case, can be simplified. As a base-case, we can take the empty list [], not a singleton list with an empty list. For the recursive case, we can consider (x:xs). Here we will need to make a distinction between x being an empty list, and x being a non-empty list. We can do that with pattern matching, or with guards:
nonEmptyCount :: [[a]] -> Int
nonEmptyCount [] = 0
nonEmptyCount (x:xs) = -- …
That being said, you do not need recursion at all. You can first filter your list, to omit empty lists, and then call length on that list:
nonEmptyCount :: [[a]] -> Int
nonEmptyCount = length . filter (…)
here you still need to fill in ….
Old fashion pattern matching should be:
import Data.List
nonEmptyCount :: [[a]] -> Int
nonEmptyCount [] = 0
nonEmptyCount (x:xs) = if null x then 1 + (nonEmptyCount xs) else nonEmptyCount xs
The following was posted in a comment, now deleted:
countNE = sum<$>(1<$)<<<(>>=(1`take`))
This most certainly will look intimidating to the non-initiated, but actually, it is equivalent to
= sum <$> (1 <$) <<< (>>= (1 `take`))
= sum <$> (1 <$) . (take 1 =<<)
= sum . fmap (const 1) . concatMap (take 1)
= sum . map (const 1) . concat . map (take 1)
which is further equivalent to
countNE xs = sum . map (const 1) . concat $ map (take 1) xs
= sum . map (const 1) $ concat [take 1 x | x <- xs]
= sum . map (const 1) $ [ r | x <- xs, r <- take 1 x]
= sum $ [const 1 r | (y:t) <- xs, r <- take 1 (y:t)] -- sneakiness!
= sum [const 1 r | (y:_) <- xs, r <- [y]]
= sum [const 1 y | (y:_) <- xs]
= sum [ 1 | (_:_) <- xs] -- replace each
-- non-empty list
-- in
-- xs
-- with 1, and
-- sum all the 1s up!
= (length . (take 1 =<<)) xs
= (length . filter (not . null)) xs
which should be much clearer, even if in a bit sneaky way. It isn't recursive in itself, yes, but both sum and the list-comprehension would be implemented recursively by a given Haskell implementation.
This reimplements length as sum . (1 <$), and filter p xs as [x | x <- xs, p x], and uses the equivalence not (null xs) === (length xs) >= 1.
See? Haskell is fun. Even if it doesn't yet feel like it, but it will be. :)

How to make a sorted list of multiples for several numbers?

I'm having trouble with an assignment from my Haskell class. I have already solved a partial problem of this task: I have to write a function that takes an Int and creates an infinite list with the multiples of that Int.
function :: Int -> [Int]
function d = [d*x | x <- [1..]]
Console:
ghci> take 10 (function 3)
gives
[3,6,9,12,15,18,21,24,27,30]
In the second task I have to extend the function so that it accepts a list of numbers and uses each value of that list as a factor (d previously). For example:
ghci> take 10 (function [3, 5])
should give
[3,5,6,9,10,12,15,18,20,21]
Already tried a list comprehension like
function d = [y*x | y <- [1..], x <- d]
but the function returns the list in an unsorted form:
[3,5,6,10,9,15,12,20,15,25]
We got the tip that we should use the modulo function of Haskell, but I have no real idea how to proceed exactly. Do you have a good tip for me?
If you think of d being a factor not as
y = x * d
but instead
y `mod` d == 0,
then you can source the list comprehension from the list [1..] and add a predicate function, for example:
function ds
| null ds = [1..]
| otherwise = [ x | x <- [1..], qualifies x ]
where
qualifies x = any (==0) $ (flip mod) <$> ds <*> [x]
A more expressive version which is perhaps easier to grasp in the beginning:
function' ds
| null ds = [1..]
| otherwise = [ x | x <- [1..], divByAnyIn ds x ]
where
divByAnyIn ds x =
case ds of
(d:ds') -> if x `mod` d == 0 then True
else divByAnyIn ds' x
_ -> False
I have a one liner.
import Data.List (nub)
f xs = nub [x|x<-[1..], d<-xs, x `mod` d == 0]
take 10 $ f [3,5] -- [3,5,6,9,10,12,15,18,20,21]
runtime should be O(n² + n*d) from the resulting list. The nub runs in O(n²). Would be nice to get rid of it.
g xs = [x |x<-[1..], let ys = map (mod x) xs in 0 `elem` ys]
This performs pretty ok. It should run in O (n*d). I also have this version which I thought performs at least as well as g, but apparently it performs better than f and worse than g.
h xs = [x |x<-[1..], or [x `mod` d == 0 |d<-xs] ]
I am not sure why that is, or is lazy as far as I can tell and I don`t see any reason why it should run slower. It especially does not scale as well when you increase the length of the input list.
i xs = foldr1 combine [[x, x+x ..] |x<- sort xs]
where
combine l [] = l
combine [] r = r
combine l#(x:xs) r#(y:ys)
| x < y = (x: combine xs r)
| x > y = (y: combine l ys)
| otherwise = (x: combine xs ys)
Not a one liner anymore, but the fastest I could come up with. I am not a hundred percent sure why it makes such a big difference on runtime if you right or left fold and if you sort the input list in advance. But it should not make a difference on the result since:
commutative a b = combine [a] [b] == combine [b] [a]
I find it completely insane to think about this Problem in terms of folding a recursive function over a list of endless lists of multiples of input coefficients.
On my System it is still about a factor of 10 slower than another solution presented here using Data.List.Ordered.
The answer here just shows the idea, it is not a optimized solution, there may exists many way to implement it.
Firstly, calculate all the value of each factors from the inputted list:
map (\d->[d*x|x<-[1..]]) xs
For example: xs = [3, 5] gives
[[3, 6, 9, ...], [5, 10, 15, ...]]
then, find the minimum value of 1st element of each list as:
findMinValueIndex::[(Int, [Int])]->Int
findMinValueIndex xss = minimum $
map fst $
filter (\p-> (head $ snd p) == minValue) xss
where minValue = minimum $ map (head . snd) xss
Once we found the list hold the minimum value, return it and remove the minimum value from list as:
sortMulti xss =
let idx = findMinValueIndex $ zip [0..] xss
in head (xss!!idx):sortMulti (updateList idx (tail $ xss!!idx) xss
So, for example, after find the first value (i.e. 3) of the result, the lists for find next value is:
[[6, 9, ...], [5, 10, 15, ...]]
repeat above steps we can construct the desired list. Finally, remove the duplicated values. Here is the completed coding:
import Data.Sequence (update, fromList)
import Data.Foldable (toList)
function :: [Int] -> [Int]
function xs = removeDup $ sortMulti $ map (\d->[d*x|x<-[1..]]) xs
where sortMulti xss =
let idx = findMinValueIndex $ zip [0..] xss
in head (xss!!idx):sortMulti (updateList idx (tail $ xss!!idx) xss)
removeDup::[Int]->[Int]
removeDup [] = []
removeDup [a] = [a]
removeDup (x:xs) | x == head xs = removeDup xs
| otherwise = x:removeDup xs
findMinValueIndex::[(Int, [Int])]->Int
findMinValueIndex xss = minimum $
map fst $
filter (\p-> (head $ snd p) == minValue) xss
where minValue = minimum $ map (head . snd) xss
updateList::Int->[Int]->[[Int]]->[[Int]]
updateList n xs xss = toList $ update n xs $ fromList xss
There is a pretty nice recursive solution
function' :: Int -> [Int]
function' d = [d * x | x <- [1..]]
braid :: [Int] -> [Int] -> [Int]
braid [] bs = bs
braid as [] = as
braid aa#(a:as) bb#(b:bs)
| a < b = a:braid as bb
| a == b = a:braid as bs # avoid duplicates
| otherwise = b:braid aa bs
function :: [Int] -> [Int]
function ds = foldr braid [] (map function' ds)
braid function builds the desired list "on the fly" using only input's head and laziness
If you want to do it with the modulo function, you can define a simple one-liner
foo ds = filter (\x -> any (== 0) [mod x d | d <- ds]) [1..]
or, in the more readable form,
foo ds = filter p [1..]
where
p x = any id [ mod x d == 0 | d <- ds]
= any (== 0) [ mod x d | d <- ds]
= not $ null [ () | d <- ds, mod x d == 0]
= null [ () | d <- ds, mod x d /= 0]
= null [ () | d <- ds, rem x d > 0]
With this, we get
> take 20 $ foo [3,5]
[3,5,6,9,10,12,15,18,20,21,24,25,27,30,33,35,36,39,40,42]
But, it is inefficient: last $ take 20 $ foo [300,500] == 4200, so to produce those 20 numbers this code tests 4200. And it gets worse the bigger the numbers are.
We should produce n numbers in time roughly proportional to n, instead.
For this, first write each number's multiples in their own list:
[ [d*x | x <- [1..]] | d <- ds ] ==
[ [d, d+d ..] | d <- ds ]
Then, merge these ordered increasing lists of numbers in an ordered fashion to produce one ordered non-decreasing list of numbers. The package data-ordlist has many functions to deal with this kind of lists:
import qualified Data.List.Ordered as O
import Data.List (sort)
bar :: (Ord a, Num a, Enum a) => [a] -> [a]
bar ds = foldr O.merge [] [ [d, d+d ..] | d <- ds ]
= O.foldt' O.merge [] [ [d, d+d ..] | d <- ds ] -- more efficient,
= O.mergeAll [ [d, d+d ..] | d <- sort ds ] -- tree-shaped folding
If we want the produced list to not contain any duplicates, i.e. create an increasing list, we can change it to
baz ds = O.nub $ foldr O.merge [] [ [d, d+d ..] | d <- ds ]
= foldr O.union [] [ [d, d+d ..] | d <- ds ]
= O.foldt' O.union [] [ [d, d+d ..] | d <- ds ]
= O.unionAll [ [d, d+d ..] | d <- sort ds ]
= (O.unionAll . map (iterate =<< (+)) . sort) ds
Oh, and, unlike the quadratic Data.List.nub, Data.List.Ordered.nub is linear, spends O(1) time on each element of the input list.

Alternative ways of defining zipWith using list comprehension without helper functions or extensions

I know you can define zipWith with zip as:
zipwith' f xs ys = [f x y | (x,y) <- zip xs ys]
But how about without zip? I read somewhere that you can do it with parallel list comprehension like this:
zipwith' f xs ys = [f x y | x <- xs | y <- ys]
But you have to add {-# LANGUAGE ParallelListComp #-} to the top of your code to make that work since it's an extension.
Are there any other ways of defining zipWith using list comprehension, preferably without helper functions or extensions?
Without zip you have to use some – arguably basic – list access functions, viz., drop and takeWhile. Both are built-in, so, not "helper functions" that you wanted to avoid:
zipW :: (a -> b -> c) -> [a] -> [b] -> [c]
zipW f xs ys = [z | [z] <- takeWhile (not.null)
[z | [z] <- takeWhile (not.null) -- ~ map (head.head)
[ [ [c | (c:_) <- [drop i r]] -- ~ take 1 . drop i
| (r:_) <- [drop i rs]] -- ~ take 1 . drop i
| let rs = [[f x y | y<- ys] | x<- xs], i <- [0..]]]]
This recovers the diagonal from the Cartesian product, taking care to handle the infinite lists (so, measuring their length is out of the question) as well as finite (so, !! can't be used).
~> zipW (,) [1..4] [10..]
[(1,10),(2,11),(3,12),(4,13)]
~> zipW (,) [1..] [10..13]
[(1,10),(2,11),(3,12),(4,13)]
And of course it is quadratic, as long as drop n is O(n), which it usually is.
If the lists are guaranteed to be infinite, it simplifies quite a bit into
zipWi f xs ys = [ rs !! i !! i | let rs = [[f x y | y<- ys] | x<- xs], i <- [0..]]
because using !! for list access is now okay (still quadratic, of course):
~> take 4 $ zipWi (,) [0..] [10..]
[(0,10),(1,11),(2,12),(3,13)]
To make it linear, the recursive solution can be encoded with unfoldr, iterate etc., but not with the list comprehensions, I think.