The two-dimensional list looks like:
1 | 2 | 3
- - - - -
4 | 5 | 6
- - - - -
7 | 8 | 9
Or in pure haskell
[ [1,2,3], [4,5,6], [7,8,9] ]
The expected output for diagonals [ [1,2,3], [4,5,6], [7,8,9] ] is
[ [1], [4, 2], [7, 5, 3], [8, 6], [9] ]
Writing allDiagonals (to include anti-diagonals) is then trivial:
allDiagonals :: [[a]] -> [[a]]
allDiagonals xss = (diagonals xss) ++ (diagonals (rotate90 xss))
My research on this problem
Similar question here at StackOverflow
Python this question is about the same problem in Python, but Python and Haskell are very different, so the answers to that question are not relevant to me.
Only one This question and answer are in Haskell, but are only about the central diagonal.
Hoogle
Searching for [[a]] -> [[a]] gave me no interesting result.
Independent thinking
I think the the indexing follows a kind of count in base x where x is the number of dimensions in the matrix, look at:
1 | 2
- - -
3 | 4
The diagonals are [ [1], [3, 2], [4] ]
1 can be found at matrix[0][0]
3 can be found at matrix[1][0]
2 can be found at matrix[0][1]
1 can be found at matrix[1][1]
That is similar to counting in base 2 up to 3, that is the matrix size minus one. But this is far too vague to be translated into code.
Starting with universe-base-1.0.2.1, you may simply call the diagonals function:
Data.Universe.Helpers> diagonals [ [1,2,3], [4,5,6], [7,8,9] ]
[[1],[4,2],[7,5,3],[8,6],[9]]
The implementation in full looks like this:
diagonals :: [[a]] -> [[a]]
diagonals = tail . go [] where
-- it is critical for some applications that we start producing answers
-- before inspecting es_
go b es_ = [h | h:_ <- b] : case es_ of
[] -> transpose ts
e:es -> go (e:ts) es
where ts = [t | _:t <- b]
The key idea is that we keep two lists: a rectangular chunk we haven't started inspecting, and a pentagonal chunk (a rectangle with the top left triangle cut out!) that we have. For the pentagonal chunk, picking out the first element from each list gives us another diagonal. Then we can add a fresh row from the rectangular, un-inspected chunk to what's left after we delete that diagonal.
The implementation may look a bit unnatural, but it's intended to be quite efficient and lazy: the only thing we do to lists is destructure them into a head and tail, so this should be O(n) in the total number of elements in the matrix; and we produce elements as soon as we finish the destructuring, so it's quite lazy/friendly to garbage collection. It also works well with infinitely large matrices.
(I pushed this release just for you: the previous closest thing you could get was using diagonal, which would only give you [1,4,2,7,5,3,8,6,9] without the extra structure you want.)
Here is a recursive version, assuming that the input is always well-formed:
diagonals [] = []
diagonals ([]:xss) = xss
diagonals xss = zipWith (++) (map ((:[]) . head) xss ++ repeat [])
([]:(diagonals (map tail xss)))
It works recursively, going from column to column. The values from one column are combined with the diagonals from the matrix reduced by one column, shifted by one row to actually get the diagonals. Hope this explanation makes sense.
For illustration:
diagonals [[1,2,3],[4,5,6],[7,8,9]]
= zipWith (++) [[1],[4],[7],[],[],...] [[],[2],[5,3],[8,6],[9]]
= [[1],[4,2],[7,5,3],[8,6],[9]]
Another version that works on the rows instead of the columns, but based on the same idea:
diagonals [] = repeat []
diagonals (xs:xss) = takeWhile (not . null) $
zipWith (++) (map (:[]) xs ++ repeat [])
([]:diagonals xss)
Compared to the specified result, the resulting diagonals are reversed. This can of course be fixed by applying map reverse.
import Data.List
rotate90 = reverse . transpose
rotate180 = rotate90 . rotate90
diagonals = (++) <$> transpose . zipWith drop [0..]
<*> transpose . zipWith drop [1..] . rotate180
It first gets the main ([1,5,9]) and upper diagonals ([2,6] and [3]); then the lower diagonals: [8,4] and [7].
If you care about ordering (i.e. you think it should say [4,8] instead of [8,4]), insert a map reverse . on the last line.
One another solution:
diagonals = map concat
. transpose
. zipWith (\ns xs -> ns ++ map (:[]) xs)
(iterate ([]:) [])
Basically, we turn
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
into
[[1], [2], [3]]
[[] , [4], [5], [6]]
[[] , [] , [7], [8], [9]]
then transpose and concat lists. Diagonals are in the reversed order.
But that's not very efficient and doesn't work for infinite lists.
Here is one approach:
f :: [[a]] -> [[a]]
f vals =
let n = length vals
in [[(vals !! y) !! x | x <- [0..(n - 1)],
y <- [0..(n - 1)],
x + y == k]
| k <- [0 .. 2*(n-1)]]
For example, using it in GHCi:
Prelude> let f vals = [ [(vals !! y) !! x | x <- [0..(length vals) - 1], y <- [0..(length vals) - 1], x + y == k] | k <- [0 .. 2*((length vals) - 1)]]
Prelude> f [ [1,2,3], [4,5,6], [7,8,9] ]
[[1],[4,2],[7,5,3],[8,6],[9]]
Assuming a square n x n matrix, there will be n + n - 1 diagonals (this is what k iterates over) and for each diagonal, the invariant is that the row and column index sum to the diagonal value (starting with a zero index for the upper left). You can swap the item access order (swap !! y !! x with !! x !! y) to reverse the raster scanning order over the matrix.
Related
This question already has answers here:
Generating integers in ascending order using a set of prime numbers
(4 answers)
Closed 4 years ago.
I am trying to generate a list of all multiples which can be represented by the form , where a, b, and c are whole numbers. I tried the following,
[ a * b * c | a <- map (2^) [0..], b <- map (3^) [0..], c <- map (5^) [0..] ]
but it only lists powers of 5 and never goes on to 2 or 3.
Edit: My apologies, it seems that I did not clarify the question enough. What I want is an ordered infinite list, and while I could sort a finite list, I feel as if there may be a solution that is more efficient.
The reason why there are only powers of 5 is that Haskell tries to evaluate every possible c for a = 2^0 and b = 3^0 and only when it is finished it goes for a = 2^0 and b = 3^1.
So this way you can only construct a finite list like this:
[ a * b * c | a <- map (2^) [0..n], b <- map (3^) [0..n], c <- map (5^) [0..n] ]
for a given n.
My first idea was starting from lists of powers of 2, 3 and 5, respectively:
p2 = iterate (2 *) 1
p3 = iterate (3 *) 1
p5 = iterate (5 *) 1
It's also easy to merge two sorted streams:
fuse [] ys = ys
fuse xs [] = xs
fuse xs#(x : xs') ys#(y : ys')
| x <= y = x : fuse xs' ys
| otherwise = y : fuse xs ys'
But then I got stuck because fuse p2 (fuse p3 p5) doesn't do anything useful. It only produces multiples of 2, or 3, or 5, never mixing factors.
I couldn't figure out a purely generative solution, so I added a bit of filtering in the form of a set accumulator. The algorithm (which is quite imperative) is:
Initialize the accumulator to {1}.
Find and remove the smallest element from the accumulator; call it n.
Emit n.
Add {2n, 3n, 5n} to the accumulator.
Go to #2 if you need more elements.
The accumulator is a set because this easily lets me find and extract the smallest element (I'm using it as a priority queue, basically). It also handles duplicates that arise from e.g. computing both 2 * 3 and 3 * 2.
Haskell implementation:
import qualified Data.Set as S
numbers :: [Integer]
numbers = go (S.singleton 1)
where
go acc = case S.deleteFindMin acc of
(n, ns) -> n : go (ns `S.union` S.fromDistinctAscList (map (n *) [2, 3, 5]))
This works, but there are things I don't like about it:
For every element we emit (n : ...), we add up to three new elements to the accumulator (ns `S.union` ... [2, 3, 5]). ("Up to three" because some of them may be duplicates that will be filtered out.)
That means numbers carries around a steadily growing data structure; the more elements we consume from numbers, the bigger the accumulator grows.
In that sense it's not a pure "streaming" algorithm. Even if we ignore the steadily growing numbers themselves, we need more memory and perform more computation the deeper we get into the sequence.
From your code:
[ a * b * c | a <- map (2^) [0..], b <- map (3^) [0..], c <- map (5^) [0..] ]
Since map (5^) [0..] is an infinite list, upon first iterations of a and b, it iterates over the said infinite list, which won't halt. That's why it is stuck at powers of 5.
Here is a solution apart from arithmetics. Note that map (2^) [0..], map (3^) [0..], and map (5^) [0..] are all lists sorted in ascending order. That means the usual merge operation is applicable:
merge [] ys = ys
merge xs [] = xs
merge (x:xs) (y:ys) = if x <= y then x : merge xs (y:ys) else y : merge (x:xs) ys
For convenience, let xs = map (2^) [0..]; let ys = map (3^) [0..]; let zs = map (5^) [0..].
To get multiples of 2 and 3, consider the following organization of said numbers:
1, 2, 4, 8, 16, ...
3, 6, 12, 24, 48, ...
9, 18, 36, 72, 144, ...
...
Judging by this, you might hope the following works:
let xys = foldr (merge . flip fmap xs . (*)) [] ys
But this doesn't work, because from the organization above, merge doesn't know which row contains the resulting head element, infinitely leaving it unevaluated. We know that the upper row contains said head element, so with following little tweak, it finally works:
let xys = foldr ((\(m:ms) ns -> m : merge ms ns) . flip fmap xs . (*)) [] ys
Do the same against zs, and here comes the desired list:
let xyzs = foldr ((\(m:ms) ns -> m : merge ms ns) . flip fmap xys . (*)) [] zs
Full code in summary:
merge [] ys = ys
merge xs [] = xs
merge (x:xs) (y:ys) = if x <= y then x : merge xs (y:ys) else y : merge (x:xs) ys
xyzs = let
xs = map (2^) [0..]
ys = map (3^) [0..]
zs = map (5^) [0..]
xys = foldr ((\(m:ms) ns -> m : merge ms ns) . flip fmap xs . (*)) [] ys
in foldr ((\(m:ms) ns -> m : merge ms ns) . flip fmap xys . (*)) [] zs
but it only lists powers of 5 and never goes on to 2 or 3.
Addressing only this bit.
To calculate numbers 2^a*3^0b*5^c you tried generating the triples (a,b,c), but got stuck producing those of the form (0,0,c). Which is why your numbers are all of the form 2^0*3^0*5^c, i.e. only powers of 5.
It's easier if you start with pairs. To produce all pairs (a,b) you can work along the diagonals of the form,
a+b = k
for each positivek. Each diagonal is easy to define,
diagonal k = [(k-x,x) | x <- [0..k]]
So to produce all pairs you'd just generate all diagonals for k<-[1..]. You want triples (a,b,c) though, but it's similar, just work along the planes,
a+b+c = k
To generate such planes just work along their diagonals,
triagonal k = [(k-x,b,c) | x <- [0..k], (b,c) <- diagonal x]
And there you go. Now just generate all 'triagonals' to get all possible triples,
triples = [triagonal k | k <- [0..]]
The other way to look at it is you wanted the numbers which are only divisible by 2,3 or 5. So check if each number starting from 1 satisfies this condition. If yes it is part of the list.
someList = [x| x<- [1..], isIncluded x]
where isIncluded is the function which decides whether x satisfies the above condition. To do this isIncluded divides the number first by 2 till it can not be divided any further by 2. Then same it does with new divided number for 3 and 5. It at ends there is 1 then we know this number is only divisible by 2,3 or 5 and nothing else.
This may not be the fastest way but still the simplest way.
isIncluded :: Int -> Bool
isIncluded n = if (powRemainder n 2 == 1) then True
else let q = powRemainder n 2
in if (powRemainder q 3 == 1) then True
else let p = powRemainder q 3
in if (powRemainder p 5 == 1) then True else False;
powRemainder is the function which takes number and base and returns the number which can not be further divided by base.
powRemainder :: Int -> Int -> Int
powRemainder 1 b = 1
powRemainder n b = if (n `mod` b) == 0 then powRemainder (n `div` b) b else n
with this when I run take 20 someList it returns [1,2,3,4,5,6,8,9,10,12,15,16,18,20,24,25,27,30,32,36].
As others already commented, your core does not work because it is analogous to the following imperative pseudocode:
for x in 0..infinity:
for y in 0..infinity:
for z in 0..infinity:
print (2^x * 3^y * 5^x)
The innermost for takes infinite time to execute, so the other two loops will never get past their first iteration. Consequently, x and y are both stuck to value 0.
This is a classic dovetailing problem: if we insist on trying all the values of z before taking the next y (or x), we get stuck on a subset of the intended outputs. We need a more "fair" way to choose the values of x,y,z so that we do not get stuck in such way: such techniques are known as "dovetailing".
Others have shown some dovetailing techniques. Here, I'll only mention the control-monad-omega package, which implements an easy to use dovetailing monad. The resulting code is very similar to the one posted in the OP.
import Control.Monad.Omega
powersOf235 :: [Integer]
powersOf235 = runOmega $ do
x <- each [0..]
y <- each [0..]
z <- each [0..]
return $ 2^x * 3^y * 5^z
I am overall confused, and looking for a very detailed and explanatory answer, of how this code works:
let xs = [1] ++ concatMap (\x -> [x+1,x*10]) xs in xs
How does concatMap know what to map and concat over?
I understand more basic examples:
let x = [1] ++ x
Here it gets evaluated like [1] ++ [1] ++ [1] ..
But I don't seem to understand the first example with concatMap. It just doesn't make sense to me. I can work with recursion frequently without problems. However, that one piece of code is very confusing.
Let's try a much simpler example:
let xs = 1 : xs in xs
OK, so xs points to a (:) node. The head-pointer from here points to 1, and the tail-pointer points to xs (i.e., back to itself). So this is either a circular list, or an infinite list. (Haskell regards the two as the same thing.) So far, so good.
Now, let's try a harder example:
let xs = 1 : map (+1) xs in xs
Do you know what this will do?
So xs points to a (:) node. The head-pointer points to 1. The tail-pointer points to the expression map (+1) xs, with xs pointing back to the top again.
If you try to "look at" the contents of this list, it will cause the map expression to start executing. The definition of map is
map f js =
case js of
k:ks -> (f k) : (map f ks)
[] -> []
So map looks at xs to see if it's [] or (:). As we know, it's (:). So the first pattern applies.
What this means is that the entire map (+1) xs expression gets overwritten with (:), with its head-pointer pointing to (+1) 1 and its tail-pointer pointing to map (+1) xs2 (with xs2 denoting a pointer to the tail of xs).
At this point, inspecting (+1) 1 turns it into 2. So now we basically have
xs = 1 : 2 : map (+1) xs2
^ |
|___________|
This cycle repeats as you examine the list. Critically, at every moment map is pointing to a node just before itself. If it ever caught up to itself, you would have a problem. But map only ever looks at nodes we've already calculated, so it's fine.
The net result, then, is xs = 1 : 2 : 3 : 4 : ...
If you can understand that, you ought to be able to understand your own more complicated example.
If you want to make your head hurt, try:
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)
This is a standard Haskell incantation for spitting out the Fibonacci numbers in O(N) time (rather than O(N*N) as the more obvious recursion would give you).
Think of concatMap as a simple composition of concat and map (concat . map).
In this particular case, you are initializing xs with 1. Once you start running your map, it will lift the lambda to operate on 1 (the first position in the list) and create a list containing two values, 2 and 10. Concat just extracts those two values from that list and puts them naked in xs, concatenating them with the existing 1. At this point, xs contains 1, 2 and 10 (xs = [1,2,10]).
Now, xs contains 1, 2 and 10 and map will repeat the process (of course, starting from the second position in the list), now operating on 2 and creating a list containing 3 and 20 and a second list containing 11 and 100 when operating on 10 (third position in the list). Concat will now extract those 4 values and append them to the contents of xs. Now xs contains 1, 2, 10, 3, 20, 11 and 100 (xs = [1,2,10,3,20,11,100]).
And you can rinse and repeat, this time map operating on the fourth position in the list (and every subsequent position), and concat doing its work to remove the new list containers and place the values directly into the top level list. As you can see, this process will generate that infinite list.
Does this help?
First, what is concat? It concatenates lists, presented to it in a list:
concat [ [1], [2], [3] ] = [ 1, 2, 3 ]
concat [ [1], [2,22], [3] ] = [ 1, 2, 22, 3 ]
and so forth. What does map do? It transforms each element in a list it is presented with:
map (1+) [1, 2, 3] = [ 2, 3, 4 ]
map (:[]) [1, 2, 3] = [ [1], [2], [3] ]
map (\x-> [x+1, x*10]) [1, 2, 3] = [ [2,10], [3,20], [4,30] ]
But concatMap f xs is the same as concat (map f xs):
concatMap (\x-> [x+1, x*10]) [1, 2, 3]
= concat (map (\x-> [x+1, x*10]) [1, 2, 3])
= concat [ [2,10], [3,20], [4,30] ]
= [ 2,10, 3,20, 4,30 ]
But, it doesn't need to see the input list through to its end, in order to proceed, producing its elements one by one. This is because of Haskell's laziness. Simply,
concat [ [2,10], [3,20], [4,30] ]
= [ 2,10, 3,20, 4,30 ]
= [ 2,10] ++ concat [ [3,20], [4,30] ]
This means that actually,
concat xs == foldr (++) [] xs
-- concat [a,b,...,n] = a ++ (b ++ (... ++ (n++[])...))
and
concatMap f xs == foldr ((++).f) [] xs
-- concatMap f [a,b,...,n] = f a ++ (f b ++ (... ++ (f n++[])...))
so it does work incrementally. For your example,
let xs = [1] ++ concatMap (\x -> [x+1,x*10]) xs in xs
== let xs = [1] ++ foldr ((++).(\x -> [x+1,x*10])) [] xs in xs
== let xs = [1] ++ foldr (\x -> ([x+1,x*10] ++)) [] xs in xs
== let xs = [1] ++ foldr (\x r -> x+1 : x*10 : r) [] xs in xs
Which simply means: xs is a list, which contains 1, and then x+1 and x*10 for each element x in xs - from the start again. We could write this down also as
xs = 1 : [y | x <- xs, y <- [x+1, x*10]]
So for 1, 2 and 10 will be "appended" at list's end, then for 2, 3 and 20 will be produced, for 10 - 11 and 100, and so on:
xs = 1 a b c d e f g h ....
[2,10]=[a,b]
= 1 2 10 c d e f g h ....
[3,20]=[c,d]
= 1 2 10 3 20 e f g h ....
[11,100]=[e,f]
....
Of course this won't be evaluated on its own; the definition is "dormant" until used, e.g. to print the first 6 elements of xs:
Prelude> let xs = 1 : [y | x <- xs, y <- [x+1, x*10]]
Prelude> take 6 xs
[1,2,10,3,20,11]
As we can see, what's really been defined here is not an infinite list - there are no infinite things after all - but a process of calculating as much of its elements as might be needed.
Yet another way of writing this definition is
xs = 1 : next xs
where
next (x:xs) = x+1 : x*10 : next xs
where the computation's structure is seen yet clearer: next "looks back" into xs as it is being defined, first 1 notch back; then 2; then 3; etc. (because it produces two new list elements for each one it consumes; this definition is thus productive). This is characteristic of a "corecursive" definition. Its calculation proceeds as
take 6 xs
= take 6 xs where xs=1:next xs -- next looks 1 element back
= 1:take 5 xs1 where xs=1:xs1; xs1=next xs
= 1:take 5 xs1 where xs1=2:10:next xs1 -- 2 elements back
= 1:2:take 4 xs2 where xs1=2:xs2; xs2=10:next xs1
= 1:2:10:take 3 xs3 where xs1=2:xs2; xs2=10:xs3; xs3=next xs1
= 1:2:10:take 3 xs3 where xs2=10:xs3; xs3=3:20:next xs2 -- 3 elements
= 1:2:10:3:take 2 xs4 where xs2=10:xs3; xs3=3:xs4; xs4=20:next xs2
= 1:2:10:3:20:take 1 xs5 where xs2=10:xs3; xs3=3:xs4; xs4=20:xs5; xs5=next xs2
= 1:2:10:3:20:take 1 xs5 where xs3=3:xs4; xs4=20:xs5; xs5=11:100:next xs3 -- 4
....
I am new to Haskell, now I have a question here.
If I have a list [[1,2],[3,4],[5,6]], and I want use a function like searchList x = 3, then output 4, how to dual with it?
Use the filter high order function:
search :: [[Int]] -> Int -> Int
search list n = head (head (filter (\(x:xs) -> x == n) list))
What this search function does is to filter the elements of the passed list of lists, selecting only the ones which have the passed value n as head. Then takes only one (The first, thats why the first (right) head is used), and then extracts the first element of that list (Using head again).
If you want to store a list of pairs, I suggest you to use tuples instead of lists as elements of the list.
EDIT: As people suggested in comments, if you use tuples there is a function lookup on the prelude that implements this kind of searching.
So what you have a list of lists and you want to search it, find the element that matches [x,y] and return y.
searchList x (y:ys) = if x == head y then last y else searchList x ys
searchList x [] = -1
Which behaves like so:
Main> :load searchlist.hs
Main> searchList 3 [ [1, 2], [3, 4], [5, 6] ]
4
Main> searchList 5 [ [1, 2], [3, 4], [5, 6] ]
6
Main> searchList 6 [ [1, 2], [3, 4], [5, 6] ]
-1
As an aside it is uncommon to use lists in Haskell if you want a fixed width, like the pairs in your list. It would be more Haskell-ish to use a list of tuples, like so.
searchListTuples x (y:ys) = if x == fst y then snd y else searchListTuples x ys
searchListTuples x [] = -1
Which of course behaves very similarly:
Main> searchListTuples 3 [ (1,2), (3,4), (5,6) ]
4
Main> searchListTuples 5 [ (1,2), (3,4), (5,6) ]
6
Main> searchListTuples 6 [ (1,2), (3,4), (5,6) ]
-1
Try with :
searchList x y = last $ head $ dropWhile (\[a,_]->a/=x) y
Or, in pointfree notation:
searchList = ((last . head) .) . dropWhile . (. head) . (/=)
I like this recursive function, but a "-1" as a bad value is not a normal Haskell idiom. Use Maybe.
searchListTuples x (y:ys) = if x == fst y then Just (snd y) else SearchListTuples x ys
searchListTuples x [] = Nothing
I have a given list, e.g. [2, 3, 5, 587] and I want to have a complete list of the combination. So want something like [2, 2*3,2*5, 2*587, 3, 3*5, 3*587, 5, 5*587, 587]. Since I am on beginner level with Haskell I am curious how a list manipulation would look like.
Additionally I am curious if the computation of the base list might be expensive how would this influence the costs of the function? (If I would assume the list has limit values, i.e < 20)
Rem.: The order of the list could be done afterwards, but I have really no clue if this is cheaper within the function or afterwards.
The others have explained how to make pairs, so I concern myself here with getting the combinations.
If you want the combinations of all lengths, that's just the power set of your list, and can be computed the following way:
powerset :: [a] -> [[a]]
powerset (x:xs) = let xs' = powerset xs in xs' ++ map (x:) xs'
powerset [] = [[]]
-- powerset [1, 2] === [[],[2],[1],[1,2]]
-- you can take the products:
-- map product $ powerset [1, 2] == [1, 2, 1, 2]
There's an alternative powerset implementation in Haskell that's considered sort of a classic:
import Control.Monad
powerset = filterM (const [True, False])
You could look at the source of filterM to see how it works essentially the same way as the other powerset above.
On the other hand, if you'd like to have all the combinations of a certain size, you could do the following:
combsOf :: Int -> [a] -> [[a]]
combsOf n _ | n < 1 = [[]]
combsOf n (x:xs) = combsOf n xs ++ map (x:) (combsOf (n - 1) xs)
combsOf _ _ = []
-- combsOf 2 [1, 2, 3] === [[2,3],[1,3],[1,2]]
So it seems what you want is all pairs of products from the list:
ghci> :m +Data.List
ghci> [ a * b | a:bs <- tails [2, 3, 5, 587], b <- bs ]
[6,10,1174,15,1761,2935]
But you also want the inital numbers:
ghci> [ a * b | a:bs <- tails [2, 3, 5, 587], b <- 1:bs ]
[2,6,10,1174,3,15,1761,5,2935,587]
This uses a list comprehension, but this could also be done with regular list operations:
ghci> concatMap (\a:bs -> a : map (a*) bs) . init $ tails [2, 3, 5, 587]
[2,6,10,1174,3,15,1761,5,2935,587]
The latter is a little easier to explain:
Data.List.tails produces all the suffixes of a list:
ghci> tails [2, 3, 5, 587]
[[2,3,5,587],[3,5,587],[5,587],[587],[]]
Prelude.init drops the last element from a list. Here I use it to drop the empty suffix, since processing that causes an error in the next step.
ghci> init [[2,3,5,587],[3,5,587],[5,587],[587],[]]
[[2,3,5,587],[3,5,587],[5,587],[587]]
ghci> init $ tails [2, 3, 5, 587]
[[2,3,5,587],[3,5,587],[5,587],[587]]
Prelude.concatMap runs a function over each element of a list, and combines the results into a flattened list. So
ghci> concatMap (\a -> replicate a a) [1,2,3]
[1, 2, 2, 3, 3, 3]
\(a:bs) -> a : map (a*) bs does a couple things.
I pattern match on my argument, asserting that it matches an list with at least one element (which is why I dropped the empty list with init) and stuffs the initial element into a and the later elements into bs.
This produces a list that has the same first element as the argument a:, but
Multiplies each of the later elements by a (map (a*) bs).
You can get the suffixes of a list using Data.List.tails.
This gives you a list of lists, you can then do the inner multiplications you want on this list with a function like:
prodAll [] = []
prodAll (h:t) = h:(map (* h) $ t)
You can then map this function over each inner list and concatenate the results:
f :: Num a => [a] -> [a]
f = concat . map prodAll . tails
So I am writing a program to generate a list of prime numbers in haskell. I create two functions shown below:
{-
Given a list of prime numbers, this function will
add the next prime number to the list. So, given the
list [2, 3], it will return [2, 3, 5]
-}
nextPrime xs = xs ++ [lastVal + nextCounts]
where
lastVal = (head . reverse) $ xs
isNextPrime y = 0 `elem` ( map ( y `mod`) xs )
nextVals = (map isNextPrime [lastVal, lastVal+1 ..] )
nextCounts = length $ takeWhile (\x -> x) nextVals
allPrimes xs = allPrimes np
where
np = nextPrime xs
Now the function 'nextPrime' is doing what it is supposed to do. However, when I do a call to allPrimes as shown below:
take 5 $ allPrimes [2,3]
The program goes into an infinite loop. I thought Haskells "lazy" features were supposed to take care of all this? What am I missing??
If you start evaluating the expression on paper you can see why laziness doesn't help here. Start with your expression:
take 5 $ allPrimes [2,3]
First, attempt to evaluate the allPrimes expression:
allPrimes [2, 3]
which becomes
allPrimes np
where
np = nextPrime [2, 3]
put the things from the where clause into the expression and it becomes
allPrimes (nextPrime [2, 3])
Now, evaluate nextPrime [2, 3] (you can do this in ghci since that function works) and get [2, 3, 5], which you can replace in the previous expression, and it becomes
allPrimes [2, 3, 5]
repeat the above and it becomes
allPrimes [2, 3, 5, 7]
and there is your problem! allPrimes never evaluated to any values, it evaluates to allPrimes applied to longer and longer lists. To see where laziness does work, try evaluating on paper a function like zip from the Prelude:
zip :: [a] -> [b] -> [(a,b)]
zip (a:as) (b:bs) = (a,b) : zip as bs
zip [1, 2, 3] ['a', 'b', 'c']
a becomes 1, as becomes [2, 3], b becomes 'a', bs becomes ['b', 'c'] so you get
(1, 'a') : zip [2, 3] ['b', 'c']
The difference here is that there is a list with a value, then the rest of the list is an expression. In your allPrimes function, you just keep getting more expressions.
For more information, look into Weak Head Normal Form however if you are new to Haskell I recommend you get comfortable with the syntax and with the basics of "Thinking in Haskell" before you start looking at things like WHNF.
I'd read Drew's answer for a good explanation of what's going wrong, but for a quick demonstration for how to make this work,
nextPrime xs = xs ++ [lastVal + nextCounts]
where
lastVal = (head . reverse) $ xs
isNextPrime y = 0 `elem` ( map ( y `mod`) xs )
-- ^ Style note, this name is super misleading, since it returns
-- false when the number is prime :)
nextVals = (map isNextPrime [lastVal, lastVal+1 ..] )
nextCounts = length $ takeWhile (\x -> x) nextVals
allPrimes xs = last np : allPrimes np
where np = nextPrime xs
Now we're constructing the list as we go, and haskell is lazy so it can grab the last element of np before evaluating the allPrimes np. In other words head (a : infiniteLoop) is a, not an infinite loop.
However this is really innefficient. Lists are singly linked in Haskell so last is O(n) as opposed to O(1) in something like Python. And ++ is also costly, O(n) for the length of the first list.
Instead
nextPrime xs = lastVal + nextCounts
where lastVal = head xs
isNextPrime = 0 `elem` map (y `rem`) xs
nextVals = map isNextPrime [lastVal ..]
nextCount = length $ takeWhile id nextVals
allPrimes xs = p : allPrimes (p:xs)
where p = nextPrime xs
So we keep the list reversed to avoid those costly traversals. We can also simplify nextPrime
import Data.Maybe
nextPrime xs = fromJust nextPrime
where isPrime y = not $ 0 `elem` map (rem y) xs
nextPrime = find isPrime [head xs ..]
Where we just search the list for the first element which is prime and add it to our list. The fromJust is normally bad, if there were no next primes we'd get an error. But since we know mathematically that there will always be a next prime, this is safe.
In the end, the code looks like
import Data.Maybe
import Data.List
nextPrime xs = fromJust nextPrime
where isPrime y = 0 `notElem` map (rem y) xs
nextPrime = find isPrime [head xs ..]
allPrimes xs = p : allPrimes (p:xs)
where p = nextPrime xs
To evaluate it, call allPrimes [2].
An even cleaner way to do this would be to have a function isPrime that returns whether a number is prime or not. And then just to have
allPrimes = filter isPrime [1..]
But I'll leave that to the curious reader.
As Drew pointed out, your function allPrimes doesn't profit from lazyness since we never have acess to what it calculates. This is because the list we want to peek into is an argument of allPrimes, not a return value.
So we need to expose the list allPrimes is building, and still keep a function call that will infinitely build the following value of this list.
Well, since allPrimes is the re-application of itself over and over, we just need a function that exposes the intermediate values. And we have one!
iterate f a == [a, f (f a),...]
So with iterate and nextPrime, we could build the following (rather strange) functions:
-- nextPrime renamed as nextPrimeList
infiniteListofListofPrimes = iterate nextPrimeList [2,3]
primeN n = (infiniteListofListofPrimes !! n) !! n
takeN n = take n (infiniteListofListofPrimes !! n)
We are generating our primes, but it's not looking great. We would rather have [primes], not redundant [[some primes]].
The next step is building the list on WHNF:
elem1:elem2:aux
where aux = newvalue:aux
Where aux will calculate the newvalue and leave everything in place for the next one.
For that we need nextPrime sticking to generating one new prime:
nextPrime xs = lastVal + nextCounts
And finding the aux that can build listOfPrimes forever.
I came up with this:
infiniteListofPrimes = 2:3:aux 2
where aux n = nextPrime (take n infiniteListofPrimes):(aux (n+1))