[Haskell-begin] Alternating sequence

I am trying to generate the following list: 2, 3, 5 -- and then alternating (+2) resp (+4) -- 7, 11, 13, 17, 19, 23 I came up with the following solution 2:3:unfoldr (\(a,b) -> Just (a,(a+b, if b == 2 then 4 else 2))) (5,2) Are there easier ways to generate the desired list? Dirk

On 21/07/2008, at 11:34 PM, Dirk Markert wrote:
I am trying to generate the following list: 2, 3, 5 -- and then alternating (+2) resp (+4) -- 7, 11, 13, 17, 19, 23
I came up with the following solution 2:3:unfoldr (\(a,b) -> Just (a,(a+b, if b == 2 then 4 else 2))) (5,2)
Are there easier ways to generate the desired list?
Hi Dirk, I doubt this is "easier", but it is a nice opportunity to show off some cyclic programming: suffix = 5 : [ x + y | (x,y) <- zip suffix (cycle [2,4])] list = 2 : 3 : suffix cycle is from the Prelude and is used above to build an "infinite" list of [2,4,2,4 ...] Note that suffix is recursive. Lazy evaluation allows us to pull values out of it whilst building it at the same time. Obviously it is important that we start building the list before trying to pull any values out of it, hence the "5 :" at the start is important. I may not have answered your question, but hopefully it is interesting nonetheless. Cheers, Bernie.

Hi Felipe,
very nice simplification. Now I can even recognize the pattern used in the
fibonacci number solution.
Thanks,
Dirk
2008/7/21 Felipe Lessa
On Mon, Jul 21, 2008 at 11:21 AM, Bernie Pope
wrote: suffix = 5 : [ x + y | (x,y) <- zip suffix (cycle [2,4])] list = 2 : 3 : suffix
'suffix' can be simplified a bit by using zipWith:
suffix = 5 : zipWith (+) suffix (cycle [2,4])
Thanks,
-- Felipe.

Hi Bernie,
I like your much more. I tried also to find a solution using cycle but
didn't succeed.
Thank you,
Dirk
2008/7/21 Bernie Pope
Hi Dirk,
I doubt this is "easier", but it is a nice opportunity to show off some cyclic programming:
suffix = 5 : [ x + y | (x,y) <- zip suffix (cycle [2,4])] list = 2 : 3 : suffix
cycle is from the Prelude and is used above to build an "infinite" list of [2,4,2,4 ...]
Note that suffix is recursive. Lazy evaluation allows us to pull values out of it whilst building it at the same time. Obviously it is important that we start building the list before trying to pull any values out of it, hence the "5 :" at the start is important.
I may not have answered your question, but hopefully it is interesting nonetheless.
Cheers, Bernie.

On Mon, Jul 21, 2008 at 9:34 AM, Dirk Markert
I am trying to generate the following list: 2, 3, 5 -- and then alternating (+2) resp (+4) -- 7, 11, 13, 17, 19, 23
I came up with the following solution 2:3:unfoldr (\(a,b) -> Just (a,(a+b, if b == 2 then 4 else 2))) (5,2)
Are there easier ways to generate the desired list?
So you've got the beginnings of an infinite list, and a rule to modify that to generate new elements. How about turning that rule into a list of its own, and then combining them? rule = cycle [ 2, 4 ] -- this will give an infinite list of 2's and 4's Combining two lists is usually done with 'zip'. But in this case, we don't just want tuples, we want the sum of each pair. You can combine lists with a function by using 'zipWith'. Start at the point where the rule kicks in. rest = 5 : zipWith (+) rest rule Now just tack on your first elements. list = 2 : 3 : rest Here it is all in one place: list = 2 : 3 : rest where rule = cycle [ 2, 4 ] rest = 5 : zipWith (+) rest rule Kurt

Hi Kurt,
thank you for the detailed explanation. Indeed, I could follow your
explanation on first reading :-)
Dirk
2008/7/21 Kurt Hutchinson
On Mon, Jul 21, 2008 at 9:34 AM, Dirk Markert
wrote: I am trying to generate the following list: 2, 3, 5 -- and then alternating (+2) resp (+4) -- 7, 11, 13, 17, 19, 23
I came up with the following solution 2:3:unfoldr (\(a,b) -> Just (a,(a+b, if b == 2 then 4 else 2))) (5,2)
Are there easier ways to generate the desired list?
So you've got the beginnings of an infinite list, and a rule to modify that to generate new elements. How about turning that rule into a list of its own, and then combining them?
rule = cycle [ 2, 4 ] -- this will give an infinite list of 2's and 4's
Combining two lists is usually done with 'zip'. But in this case, we don't just want tuples, we want the sum of each pair. You can combine lists with a function by using 'zipWith'. Start at the point where the rule kicks in.
rest = 5 : zipWith (+) rest rule
Now just tack on your first elements.
list = 2 : 3 : rest
Here it is all in one place:
list = 2 : 3 : rest where rule = cycle [ 2, 4 ] rest = 5 : zipWith (+) rest rule
Kurt

Another way to define 'rule' here, just for kicks:
rule = 2 : 4 : rule
On Mon, Jul 21, 2008 at 11:57 AM, Dirk Markert
Hi Kurt,
thank you for the detailed explanation. Indeed, I could follow your explanation on first reading :-)
Dirk
2008/7/21 Kurt Hutchinson
: On Mon, Jul 21, 2008 at 9:34 AM, Dirk Markert
wrote: I am trying to generate the following list: 2, 3, 5 -- and then alternating (+2) resp (+4) -- 7, 11, 13, 17, 19, 23
I came up with the following solution 2:3:unfoldr (\(a,b) -> Just (a,(a+b, if b == 2 then 4 else 2))) (5,2)
Are there easier ways to generate the desired list?
So you've got the beginnings of an infinite list, and a rule to modify that to generate new elements. How about turning that rule into a list of its own, and then combining them?
rule = cycle [ 2, 4 ] -- this will give an infinite list of 2's and 4's
Combining two lists is usually done with 'zip'. But in this case, we don't just want tuples, we want the sum of each pair. You can combine lists with a function by using 'zipWith'. Start at the point where the rule kicks in.
rest = 5 : zipWith (+) rest rule
Now just tack on your first elements.
list = 2 : 3 : rest
Here it is all in one place:
list = 2 : 3 : rest where rule = cycle [ 2, 4 ] rest = 5 : zipWith (+) rest rule
Kurt
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

Dirk Markert wrote:
I am trying to generate the following list: 2, 3, 5 -- and then alternating (+2) resp (+4) -- 7, 11, 13, 17, 19, 23
I came up with the following solution 2:3:unfoldr (\(a,b) -> Just (a,(a+b, if b == 2 then 4 else 2))) (5,2)
Are there easier ways to generate the desired list?
Use a left scan result = 2:3:scanl (+) 5 (cycle [2,4]) Regards, apfelmus

Hi apfelmus,
of course a left scan. What else!
Really a very, very nice solution.
Thank you,
Dirk
2008/7/21 apfelmus
Use a left scan
result = 2:3:scanl (+) 5 (cycle [2,4])
Regards, apfelmus
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
participants (6)
-
Andrew Wagner
-
apfelmus
-
Bernie Pope
-
Dirk Markert
-
Felipe Lessa
-
Kurt Hutchinson