05.03.2016 Views

Programming in Scala”

fpiscompanion

fpiscompanion

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Chapter notes 16<br />

This may seem like it shouldn’t work. The stream is referenc<strong>in</strong>g itself <strong>in</strong> its own tail! But the trick<br />

is that the #:: constructor is non-strict <strong>in</strong> its second argument. The evaluation of cyclic will stop<br />

without expand<strong>in</strong>g the expression 1 #:: cyclic. It’s not until somebody takes the tail of the tail<br />

of cyclic that the recursive reference is expanded, and aga<strong>in</strong> it expands only one element at a time,<br />

allow<strong>in</strong>g for an <strong>in</strong>f<strong>in</strong>ite, cyclic stream.<br />

Note that the cyclic stream is reus<strong>in</strong>g its own structure. cyclic.tail.tail is not a new stream<br />

that looks like cyclic. It really is the same object as cyclic <strong>in</strong> every sense:<br />

scala> cyclic.tail.tail eq cyclic<br />

res0: Boolean = true<br />

This technique is sometimes called “Ty<strong>in</strong>g the Knot”. For more <strong>in</strong>formation see the Haskell.org<br />

article⁷¹.<br />

However, be careful of creat<strong>in</strong>g such structures us<strong>in</strong>g the Scala standard library’s Stream. They can<br />

be quite fragile. The reason is that scala.Stream is is strict <strong>in</strong> the head element and it will also<br />

memoize⁷² the computed contents, which can lead to memory leaks.<br />

Stream.apply<br />

Be careful us<strong>in</strong>g Stream.apply, both <strong>in</strong> the standard library and <strong>in</strong> the exercises: they are constructed<br />

us<strong>in</strong>g repeated parameters, which are always strict. This means that e.g.<br />

Stream({pr<strong>in</strong>tln("One"); 1}, {pr<strong>in</strong>tln("Two"); 2}, {pr<strong>in</strong>tln("Three"); 3})<br />

will immediately pr<strong>in</strong>t One, Two, Three. Although the Stream will be constructed lazily, the contents<br />

have already been evaluated.<br />

For truly lazily constructed Streams you can always resort to #:: (which still evaluates the head<br />

value strictly!) or nested cons(..,cons(..,..)) operators <strong>in</strong> the exercises.<br />

Notes on chapter 6: Purely functional state<br />

State <strong>in</strong> Scalaz<br />

The Scalaz library⁷³ supplies a State data type⁷⁴ that is a specialization of a more general type<br />

IndexedStateT⁷⁵, where State[S,A] = IndexedStateT[Id, S, S, A] and Id[A] = A.<br />

⁷¹http://www.haskell.org/haskellwiki/Ty<strong>in</strong>g_the_Knot<br />

⁷²http://en.wikipedia.org/wiki/Memoization<br />

⁷³http://github.com/scalaz/scalaz<br />

⁷⁴http://docs.typelevel.org/api/scalaz/stable/7.1.0-M3/doc/#scalaz.package\protect\char”0024\relax\protect\char”0024\relaxState\protect\<br />

char”0024\relax<br />

⁷⁵http://docs.typelevel.org/api/scalaz/stable/7.1.0-M3/doc/#scalaz.IndexedStateT

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!