# Yann Moisan

Scala, Web, Linux…

# Scalaz

The aim of this page is to show the use of Scalaz on the project. Scalaz defines itself as an extension to the core Scala library for functional programming

## option

```scala> 1.some.toSuccess("error")
res32: scalaz.Validation[String,Int] = Success(1)

scala> None.toSuccess("error")
res33: scalaz.Validation[String,A] = Failure(error)
```

## sequence

Scalaz API is hard to read :

```trait TraverseOps[F[_], A] extends scala.AnyRef with scalaz.syntax.Ops[F[A]] {
final def sequence[G[_], B](implicit ev : scalaz.Leibniz.===[A, G[B]], G : scalaz.Applicative[G]) : G[F[B]] = { /* compiled code */ }
}
```

Here is some explanation from Scalaz Traverse examples :

```// An easy to understand first step in using the Traverse typeclass
// is the sequence operation, which given a Traverse[F] and
// Applicative[G] turns F[G[A]] into G[F[A]]. This is like "turning
// the structure 'inside-out'":
```

So, it allows to do simple things :

```scala> List(Option(1), Option(2)).sequence
res8: Option[List[Int]] = Some(List(1, 2))

scala> List(Option(1), None).sequence
res9: Option[List[Int]] = None
```
```// The effect of the inner Applicative is used, so in the case of
// the Option applicative, if any of the values are None instead of
// Some, the result of the entire computation is None:
```

Obviously, it can be done without Scalaz by implementing a `sequence` method :

```def sequence[A](l: List[Option[A]]): Option[List[A]] =
l.foldRight(Some(Nil: List[A]):Option[List[A]])((oa, ola) => oa.flatMap(a => ola.map(la => a :: la)))
```

But it seems like reinventing the wheel, and it will only work for `Option`, and not for all `Applicative`s.

## Validation

In scala, we use `Either` as a return type to represent a method that can fail. Unfortunately, the type `Either` has some limitations and doesn't allow to collect a list of errors. Let's introduce new datatypes `Validation` to resolve this issue :

```scala> def f = { x : String => if (!x.toLowerCase.equals(x)) "only lowercase allowed".failure[String] else "ok2".success }
f: String => scalaz.Validation[String,String]

scala> def g = { x : String => if (x.contains(" ")) "no space allowed".failure[String] else "ok1".success[String] }
g: String => scalaz.Validation[String,String]

scala> (f("A b") |@| g("A b")) {_ + _}
res28: scalaz.Unapply[scalaz.Apply,scalaz.Validation[String,String]]{type M[X] = scalaz.Validation[String,X]; type A = String}#M[String] = Failure(only lowercase allowedno space allowed)
```

Here is some explanation from Scalaz Apply examples :

```// |@| is refered to as "applicative builder", it allows you to
// evaluate a function of multiple arguments in a context, similar
// to apply2, apply3, apply4, etc:
```

## Kleisli

It allows to combine monadic functions

```scala> def f = { x : Int => Option(x+1) }
f: Int => Option[Int]

scala> def g = { x : Int => Option(x*2) }
g: Int => Option[Int]

scala> Kleisli(f) >=> Kleisli(g)
res10: scalaz.Kleisli[Option,Int,Int] = scalaz.KleisliFunctions\$\$anon\$17@6442084f

scala> res10(3)
res11: Option[Int] = Some(8)
```

Obviously, it can also be done without Scalaz, by implementing a `compose` method :

```scala> def compose[A,B,C](f: A => Option[B], g: B => Option[C]) : A => Option[C] = a => f(a).flatMap(g)
compose: [A, B, C](f: A => Option[B], g: B => Option[C])A => Option[C]

scala> compose(f,g)(3)
res1: Option[Int] = Some(8)
```

But it seems like reinventing the wheel, and it will only work for `Option`, and not for all `Monad`s.

### To go further

Here is some features that are not used but could be useful.

• tagged type to add type safety on `Id` (compositeIds could return `List[Id @@ Composite]`