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

like this will result <strong>in</strong> a compile error like "covariant type A occurs <strong>in</strong> contravariant position".<br />

Scala must enforce that no such contradictions exist, or we could circumvent the type-checker and<br />

easily write programs that gave a type error at runtime, <strong>in</strong> the form of a ClassCastException.<br />

The more complicated signature fixes the contradiction by not mention<strong>in</strong>g A <strong>in</strong> any of the function<br />

arguments:<br />

def orElse[B >: A](o: Option[B]): Option[B]<br />

Covariant and contravariant positions<br />

A type is <strong>in</strong> covariant position (positive) if it is <strong>in</strong> the result type of a function, or more generally is<br />

the type of a value that is produced.<br />

A type is <strong>in</strong> contravariant position (negative) if it’s <strong>in</strong> the argument type of a function, or more<br />

generally is the type of a value that is consumed.<br />

For example, <strong>in</strong> def foo(a: A): B, the type A is <strong>in</strong> contravariant position and B is <strong>in</strong> covariant<br />

position, all th<strong>in</strong>gs be<strong>in</strong>g equal.<br />

We can extend this reason<strong>in</strong>g to higher-order functions. In def foo(f: A => B): C, the type A => B<br />

appears <strong>in</strong> negative (contravariant) position. This means the variance of the types A and B is flipped.<br />

The type A appears <strong>in</strong> a negative position of a type <strong>in</strong> negative position. So just like the negation of<br />

a negative is a positive, this means A is actually <strong>in</strong> covariant position. And s<strong>in</strong>ce B is <strong>in</strong> the covariant<br />

position of a type <strong>in</strong> contravariant position, it’s the negation of a positive, so B is <strong>in</strong> contravariant<br />

position overall.<br />

We can always count the position of a polymorphic type this way. Result types are positive, and<br />

argument types are negative. The arguments to arguments are positive, arguments to arguments to<br />

arguments are negative, and so on.<br />

Notes on chapter 5: Strictness and laz<strong>in</strong>ess<br />

Non-strictness vs laz<strong>in</strong>ess<br />

The Haskell website⁵⁸ has a good explanation of the difference between non-strictness and laz<strong>in</strong>ess.<br />

In short, “non-strict” just means “not strict”. There are many possible evaluation strategies⁵⁹ one<br />

could employ when evaluat<strong>in</strong>g a program, and strict evaluation⁶⁰ is one of them. Non-strict<br />

evaluation⁶¹ is a class of evaluation strategies, and lazy evaluation⁶² is one non-strict strategy (also<br />

known as “call-by-need”).<br />

⁵⁸http://www.haskell.org/haskellwiki/Lazy_vs._non-strict<br />

⁵⁹http://en.wikipedia.org/wiki/Evaluation_strategy<br />

⁶⁰http://en.wikipedia.org/wiki/Strict_evaluation<br />

⁶¹http://en.wikipedia.org/wiki/Non-strict_evaluation#Non-strict_evaluation<br />

⁶²http://en.wikipedia.org/wiki/Lazy_evaluation

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

Saved successfully!

Ooh no, something went wrong!