Scalaz is to Scala what Guava is to Java : a must to know library ! But unfortunately, learning scalaz is not so easy.
This hand's on focuses on concrete use cases instead of complex theory. The goal is to show that you can use scalaz to improve your code and remove some boilerplate.
I've chosen some pieces of code that can benefit from scalaz. For each, a test suite will help you understand what the code does.
sbt test
Scalaz 7.1 is used, because it's the version that you depend on with Play 2.4/2.5
- add the dependency in
build.sbt
libraryDependencies += "org.scalaz" %% "scalaz-core" % "7.1.5"
- import stuff
import scalaz._
import Scalaz._
- Since scala 2.11.8, the tab completion find methods resulting from an implicit conversion. And scalaz uses a lot of them ! e.g. type
1.show<Tab>
in the REPL
@ 1.show
final def show: scalaz.Cord
- If you want to find the source of an implicit conversion, use the following code
@ import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._
@ showCode(reify { 1.show }.tree)
res14: String = "Scalaz.ToShowOps(1)(Scalaz.intInstance).show"
Main symbols - thanks to reactormonk
Symbol | Explanation | Hint |
---|---|---|
\/ |
Right-leaning Either | Split ways, go one way or the other |
-\/ |
Left value of \/ |
- is on the left side |
\/- |
Right value of \/ |
- is on the right side |
>>= |
flatMap |
shove result into |
>> |
flatMap(_ => ..) |
shove into, but ignore the result |
` | @ | ` |
` | + | ` |
`> | ` | fa.map(_ => b) |
*> |
fa.flatMap(_ => fb) |
Do both effects, left to right, use right value |
<* |
fa.flatMap(a => fb.map(_ => a)) |
Do both effects, left to right, use left value |
<=< |
Alias for compose |
Left fish |
>=> |
Alias for andThen |
Right fish |
=== |
Type-safe equality check | Really equals |
/== |
Type-safe not-equality check | Slashed equals |
`? | ?` | Type-safe order comparison |
Your mission, if you accept it, is to implement all methods marked as todo using Scalaz. All the unit tests are provided and you don't need to modify them. When your implementation will be correct, the tests will pass.
Here are some hints if you need them.
- Step 1 : solve compilation issue
- Step 2 : use scalaz
- replace
case class
with scalazTag
- replace
Either
with scalaz\/
- replace
Try
withscalaz.Validation
- Hint : Monoid (don't worry, it's such a pedantic word to say a type that you can merge).
trait Monoid[F] { self =>
def append(f1: F, f2: => F): F
}
- Hint : use
Traverse
to transformF[G[A]]
intoG[F[A]]
- Hint : use
OptionT
, a tool for composing monads.
- Hint : use a Reader monad, to inject the dependency.
- examples
- learning scalaz
- Dead-Simple Dependency Injection : Video / Slides
- Video - Scalaz for the Rest of Us at Yelp
- Scalaz Gateway Drugs Video / Slides
- Training material on Scalaz 7 usage
- Typeclassopedia for scala
- scalaz 102
- roll-your-own-scala