
i'm trying to figure out how to think out the circular definition for an infinite list and would appreciate suggestions. consider ones = 1 : ones this essentially says 1 : (1 : (1 : (1 : ones))) with ones being given by the original def. however, i had trouble with this one fib = 1 : 1 : [ a+b | (a,b) <- zip fib (tail fib) ] initially, i tried building it element by element and got stuck when i thought of what was fib tail fib and what was being zipped so i thought it out differently by assuming the infinite list was already created in the following fashion. fib is [1,1,a,b,c,d,e, ..] tail fib is [1,a,b,c,d,e,f, ..] to find a, we zip fib and tail fib getting (1,1) and add getting 2: fib is [1,1,2,b,c,d,e, ..] tail fib is [1,2,b,c,d,e,f, ..] get b from the next zip (1,2) and add giving 3: fib is [1,1,2,3,c,d,e, ..] tail fib is [1,2,3,c,d,e,f, ..] c comes from (2,3) which adds to 5: fib is [1,1,2,3,5,d,e, ..] tail fib is [1,2,3,5,d,e,f, ..] this way of thinking about it makes sense to me, but i'd be curious to know if it is proper thinking. it seems to me that if we consider the list to be already built, we can apply zip successively to get the next part of it, but if we think recursively we start at the beginning at each recursive level and go nowhere. -- In friendship, prad ... with you on your journey Towards Freedom http://www.towardsfreedom.com (website) Information, Inspiration, Imagination - truly a site for soaring I's

On Mon, Jun 21, 2010 at 8:58 PM, prad
it seems to me that if we consider the list to be already built, we can apply zip successively to get the next part of it, but if we think recursively we start at the beginning at each recursive level and go nowhere.
That's a funny way to say it : to me recursive thinking has always been about assuming I already have a function that works on smaller (in some sense) cases, writing the function knowing that and then figuring what's the base case we're tending toward and handling it non-recursively. That's what recursion is about for me and I've always found easier to think about it like that rather than always expansing the recursive calls (I also find it easier than thinking iteratively nowadays but YMMV). In other words what you describe as your new method to think about infinite structure is the only way I approach recursion (of structure or functions). I would say it's a perfectly valid approach as long as you don't forget to handle the base case (here it's the explicit definition of the first two elements). -- Jedaï

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 6/21/10 17:43 , Chaddaï Fouché wrote:
On Mon, Jun 21, 2010 at 8:58 PM, prad
wrote: it seems to me that if we consider the list to be already built, we can apply zip successively to get the next part of it, but if we think recursively we start at the beginning at each recursive level and go nowhere.
That's a funny way to say it : to me recursive thinking has always been about assuming I already have a function that works on smaller (in some sense) cases, writing the function knowing that and then figuring what's the base case we're tending toward and handling it non-recursively. That's what recursion is about for me and I've always found easier to think about it like that rather than always expansing the recursive calls (I also find it easier than thinking iteratively nowadays but YMMV).
I think of it a bit like proofs: prove the base case, prove the inductive case, therefore the proof applies to all cases (which is equivalent to being infinite). -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAkwf3boACgkQIn7hlCsL25UI9ACeM7OBLjSZnUuzHmfC0ZKge4ti n2UAoLn09TYwvUAvSTCOeJHMAQZa/3FI =rDt7 -----END PGP SIGNATURE-----

prad wrote:
i'm trying to figure out how to think out the circular definition for an infinite list and would appreciate suggestions.
consider ones = 1 : ones this essentially says 1 : (1 : (1 : (1 : ones))) with ones being given by the original def.
however, i had trouble with this one fib = 1 : 1 : [ a+b | (a,b) <- zip fib (tail fib) ]
The Haskell wikibook has some material on this: http://en.wikibooks.org/wiki/Haskell/Denotational_semantics Basically, the key question is: "What is a recursive definition, anyway?". The answer to that is that any recursively defined value is obtained from a sequence of approximations. We start with the worst approximation called ⊥ ("bottom") which basically means "it's undefined, we don't know what it is". fib_0 = ⊥ To get a better approximation, we apply the definition of fib to that. fib_1 = 1 : 1 : [ a+b | (a,b) <- zip fib_0 (tail fib_0) ] = 1 : 1 : [ a+b | (a,b) <- zip ⊥ (tail ⊥) ] = 1 : 1 : [ a+b | (a,b) <- zip ⊥ ⊥ ] = 1 : 1 : [ a+b | (a,b) <- ⊥ ] = 1 : 1 : ⊥ To get an even better approximation, we once again apply the equation for fib to this approximation: fib_2 = 1 : 1 : [ a+b | (a,b) <- zip fib_1 (tail fib_1) ] = 1 : 1 : [ a+b | (a,b) <- zip (1:1:⊥) (tail (1:1:⊥)) ] = 1 : 1 : [ a+b | (a,b) <- zip (1:1:⊥) (1:⊥) ] = 1 : 1 : [ a+b | (a,b) <- (1,1):⊥ ] = 1 : 1 : 2 : ⊥ and so on and so on. The limit of these approximations fib_0 = ⊥ fib_1 = 1 : 1 : ⊥ fib_2 = 1 : 1 : 2 : ⊥ fib_3 = 1 : 1 : 2 : 3 : ⊥ ... is the infinite list fib = 1 : 1 : 2 : 3 : 5 : ... This is the thinking that you have described, with a minor, but crucial change. Namely, it's not clear that your list elements a,b,c,d, etc. exist a priori, i.e. that the list is already created in this form. For instance, it wouldn't be right to say that the example foo = 1 : 1 : loop where loop = loop can be written as foo = [1,1,a,b,c, ..] because the recursion simply won't progress past foo = 1 : 1 : ⊥ The formulation with ⊥ can handle such cases. In other words, your thinking is right but somewhat restricted to a few particular examples while the method using ⊥ as shown here will *always* apply. The key message to take away is that you also need some way (⊥) to express recursive definitions that might loop forever. Regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com

On Wed, 23 Jun 2010 13:02:38 +0200
Heinrich Apfelmus
The answer to that is that any recursively defined value is obtained from a sequence of approximations.
that is a wonderful and detailed explanation. i didn't ever understand what bottom was. thx for the wikibooks link as well.
The key message to take away is that you also need some way (⊥) to express recursive definitions that might loop forever.
yes i understand this now. my a,b,c was put there because i just assumed nothing would be evaluated till required so the idea of a terminating condition didn't really seem necessary especially on an infinite list, but i'm getting a feel for how you worked it in with the concept of an approximation which is certainly something i had never thought of in that way. thank you very much for helping alter my reasoning process and that looks like a great site you have: http://apfelmus.nfshost.com/ i'll be dropping by! -- In friendship, prad ... with you on your journey Towards Freedom http://www.towardsfreedom.com (website) Information, Inspiration, Imagination - truly a site for soaring I's
participants (4)
-
Brandon S Allbery KF8NH
-
Chaddaï Fouché
-
Heinrich Apfelmus
-
prad