Related
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)]
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. :)
The point of this assignment is to understand list comprehensions.
Implementing Goldbach's conjecture for some natural number (otherwise the behavior does not matter) using several pre-defined functions and under the following restrictions:
no auxiliary functions
no use of where or let
only one defining equation on the left-hand side and the right-hand side must be a list comprehension
the order of the pairs in the resulting list is irrelevant
using functions from Prelude is allowed
-- This part is the "library"
dm :: Int -> [ Int ] -> [ Int ]
dm x xs = [ y | y <- xs , y `mod ` x /= 0]
da :: [ Int ] -> [ Int ]
da ( x : xs ) = x : da ( dm x xs )
primes :: [ Int ]
primes = da [2 ..]
-- Here is my code
goldbach :: Int -> [(Int,Int)]
-- This is my attempt 1
goldbach n = [(a, b) | n = a + b, a <- primes, b <- primes, a < n, b < n]
-- This is my attempt 2
goldbach n = [(a, b) | n = a + b, a <- takeWhile (<n) primes, b <- takeWhile (<n) primes]
Expected result: a list of all pairs summing up to the specified integer. But GHC complains that in the comprehension, n is not known. My gut tells me I need some Prelude function(s) to achieve what I need, but which one?
Update
parse error on input ‘=’
Perhaps you need a 'let' in a 'do' block?
e.g. 'let n = 5' instead of 'n = 5'
Disregarding the weird error you are talking about, I think that the problem you actually have is the following:
As mentioned by #chi and me, you can't use a and b in your final comprehension before you define a and b.
so you have to move it to the and.
Also: equality of integers is checked with (==) not (=) in haskell.
So you also need to change that.
This would be the complete code for your final approach:
goldbach n = [(a, b) | a <- takeWhile (<n) primes, b <- takeWhile (<n) primes, n == a + b]
A small test yields:
*Main> goldbach 5
[(2,3),(3,2)]
Update
If you want to achieve what you wrote in your comment, you can just add another condition to your comprehension
n `mod` 2 == 0
or even better: Define your funtion with a guard like this:
goldbach n
| n `mod` 2 == 0 = [(a, b) | a <- takeWhile (<n) primes, b <- takeWhile (<n) primes, n == a + b]
| otherwise = []
However, if I am not mistaken this has nothing to do with the actual Godbach conjecture.
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.
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.