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 38<br />

Notes on chapter 12: Applicative and traversable<br />

functors<br />

The cost of power<br />

There is a tradeoff between applicative APIs and monadic ones. Monadic APIs are strictly more<br />

powerful and flexible, but the cost is a certa<strong>in</strong> loss of algebraic reason<strong>in</strong>g.<br />

The difference is easy to demonstrate <strong>in</strong> theory, but takes some experience to fully appreciate <strong>in</strong><br />

practice.<br />

Consider composition <strong>in</strong> a monad, via compose (Kleisli composition):<br />

val foo: A => F[B] = ???<br />

val bar: B => F[C] = ???<br />

val baz: A => F[C] = bar compose foo<br />

There is no way that the implementation of the compose function <strong>in</strong> the Monad[F] <strong>in</strong>stance can<br />

<strong>in</strong>spect the values foo and bar. They are functions, so the only way to “see <strong>in</strong>side” them is to<br />

give them arguments. The values of type F[B] and F[C] respectively are not determ<strong>in</strong>ed until the<br />

composite function runs.<br />

Contrast this with comb<strong>in</strong><strong>in</strong>g values with map2:<br />

val quux: F[A] = ???<br />

val corge: F[B] = ???<br />

val grault: F[C] = map2(quux, corge)(f)<br />

Here the implementation of map2 can actually look at the values quux and corge, and take different<br />

paths depend<strong>in</strong>g on what they are. For <strong>in</strong>stance, it might rewrite them to a normal form for improved<br />

efficiency. If F is someth<strong>in</strong>g like Future, it might decide to start immediately evaluat<strong>in</strong>g them on<br />

different threads. If the data type F is applicative but not a monad, then the implementation has this<br />

flexibility universally. There is then never any chance that an expression <strong>in</strong> F is go<strong>in</strong>g to <strong>in</strong>volve<br />

functions of the form A => F[B] that it can’t see <strong>in</strong>side of.<br />

The lesson here is that power and flexibility <strong>in</strong> the <strong>in</strong>terface often restricts power and flexibility <strong>in</strong><br />

the implementation. And a more restricted <strong>in</strong>terface often gives the implementation more options.<br />

See this StackOverflow question¹⁶⁴ for a discussion of the issue with regard to parsers.<br />

See also the end of the note below on “Applicative laws”, for an example of the loss of algebraic<br />

reason<strong>in</strong>g that comes with mak<strong>in</strong>g an API monadic rather than applicative.<br />

¹⁶⁴http://stackoverflow.com/questions/7861903/what-are-the-benefits-of-applicative-pars<strong>in</strong>g-over-monadic-pars<strong>in</strong>g

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

Saved successfully!

Ooh no, something went wrong!