In scalaz when we define a module, we additionally define implicit, helper functions. Here is an example of definition and how it could be used by a client:
trait Functor[F[_]] {
def map[A,B](fa: F[A])(f: A => B): F[B]
}
object Functor {
def fmap[F[_], A,B](as:F[A])(f:A=>B)
(implicit ff:Functor[F]):F[B] =
ff.map(as)(f)
implicit val listFunctor = new Functor[List] {
def map[A,B](as: List[A])(f: A => B): List[B] = as map f
}
}
...
import com.savdev.NewLibrary._
val r = fmap(List(1,2))(_.toString)
final class FunctorOps[F[_], A](self: F[A])(implicit ff:Functor[F]){
def qmap[B](f:A=>B):F[B] = ff.map(self)(f)
}
trait FunctorSyntax {
implicit def ToFunctorOps[F[_],A](v: F[A])(implicit F0: Functor[F]) =
new FunctorOps[F,A](v)
}
object NewLibrary extends FunctorSyntax
...
import com.savdev.NewLibrary._
val r = fmap(List(1,2))(_.toString)
The code is slightly changed. But the idea is that we define:
- An abstraction and its API (algebra)
- Define helper generic functions that use implicits and implicits themselves
- Enrich existing types to be able to use our new abstraction. Implicit convertion is used for that. In scalaz we define a final class for a wrapper and implicit converters in traits
All above, the motivation of it and how it can be used by a client is clear. But in to each such module definition, there is also a related *Syntax
class. I cannot understand the purpose of it. Can you please exlain, why it is needed and HOW it can be used in a client code.
Aucun commentaire:
Enregistrer un commentaire