tag:blogger.com,1999:blog-6818189468244276547.post5240976571360820094..comments2023-10-10T15:54:46.212+01:00Comments on Quoi qu'il en soit: Scala: C style iterate function for building listsTimAhttp://www.blogger.com/profile/03169884264169945941noreply@blogger.comBlogger5125tag:blogger.com,1999:blog-6818189468244276547.post-27871539021216851352009-10-15T12:47:26.795+01:002009-10-15T12:47:26.795+01:00Notice that is 2.8. There are many, many iterator ...Notice that is 2.8. There are many, many iterator builders in Scala 2.8. I think this one, in particular, is one of the new builders.<br /><br />There are two advantages of Stream over iterators. First, it is functional. Relevantly, if you pass a reference to some part of the stream around, you need not be concerned about the reference you kept being modified.<br /><br />The second advantage, closely related to the first, is that a Stream persists. If you make a Stream for prime numbers (such as the one in the API docs for Stream), you may rest assured that each element will be computed only once. If you ever need it again, and haven't lost the reference to it, it will be available in memory.Danielhttps://www.blogger.com/profile/07505997833685327219noreply@blogger.comtag:blogger.com,1999:blog-6818189468244276547.post-75386466623660337512009-10-15T09:57:58.198+01:002009-10-15T09:57:58.198+01:00@Daniel: Thanks (and doh!). The moral of the story...@Daniel: Thanks (and doh!). The moral of the story is: learn he APIs. I'll update my blog so as not to mislead anybody about the simplest solution. The journey has been a good one though. What is intereresting is the radically differency implementations of Iterorator.iterate and <br />def iterate[A]<br /> (seed: A)(step: A => A)<br /> : Stream[A] <br /> = seed #:: iterate(step(seed))(step)<br />With the former using internal state and the latter using the lazy Stream mechanism (whatever that is). Is there is anything you can do with a Stream based iterate function that you can't do with Iterator.iterate?TimAhttps://www.blogger.com/profile/03169884264169945941noreply@blogger.comtag:blogger.com,1999:blog-6818189468244276547.post-44587126676094821862009-10-14T19:53:01.090+01:002009-10-14T19:53:01.090+01:00Welcome to Scala version 2.8.0.r18637-b20090903020...Welcome to Scala version 2.8.0.r18637-b20090903020149 (Java HotSpot(TM) Client VM, Java 1.6.0_16).<br />Type in expressions to have them evaluated.<br />Type :help for more information.<br /><br />scala> val x = Iterator.iterate(0)(_ + 1)<br />x: Iterator[Int] = non-empty iterator<br /><br />scala> x takeWhile (_ < 20)<br />res0: Iterator[Int] = non-empty iterator<br /><br />scala> res0.toList<br />res1: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)Danielhttps://www.blogger.com/profile/07505997833685327219noreply@blogger.comtag:blogger.com,1999:blog-6818189468244276547.post-76583963339533283332009-10-13T23:08:21.315+01:002009-10-13T23:08:21.315+01:00@Johan: Thanks, this is great stuff. 25 years ago ...@Johan: Thanks, this is great stuff. 25 years ago I had the good chance to do some Miranda at UKC (under the watchful glare of the now Proj Simon Thomson) Finally it is paying off, and I have a vague clue of what you are talking about! <br />By the way lazy_:: is gone and now known as #:: in the latest version of scala 2.8pre that I am using (via eclipse plugin)TimAhttps://www.blogger.com/profile/03169884264169945941noreply@blogger.comtag:blogger.com,1999:blog-6818189468244276547.post-55018119222682993722009-10-13T12:06:51.197+01:002009-10-13T12:06:51.197+01:00This function is very similar to until (but with a...This function is very similar to until (but with a reversed predicate) in Haskell: http://www.haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v%3Auntil. Basically, it's <i>iterate</i> and <i>takeWhile</i>.<br /><br />Unfortunately, the <i>iterate</i> functions in Scala's traversable collections are not polymorphic. (Maybe it's because it would only work for lazy collections.) But here's one for Stream:<br /><br />def iterate[A](step: A => A)(seed: A): Stream[A] = seed lazy_:: iterate(step)(step(seed))<br /><br />Now it's easy to write iterateFor:<br /><br />def iterateFor[A](predicate: A => Boolean)(step: A => A)(seed: A): Stream[A] = iterate(step)(seed) takeWhile predicate<br /><br />or, all in one go:<br /><br />def until[A](...) = if (predicate(seed)) seed lazy_:: until(predicate)(step)(step(seed)) else Stream.emptyJohanhttps://www.blogger.com/profile/02361156710674732570noreply@blogger.com