0

Just started learning Scalaz. Here is my code

trait Monoid[A] { def mappend(a1: A, a2: A): A def mzero: A } object Monoid { implicit val IntMonoid: Monoid[Int] = new Monoid[Int] { def mappend(a1: Int, a2: Int): Int = a1 + a2 def mzero: Int = 0 } implicit val StringMonoid: Monoid[String] = new Monoid[String] { def mappend(a1: String, a2: String): String = a1 + a2 def mzero: String = "" } } trait MonoidOp[A] { val F: Monoid[A] val value: A def |+|(a2: A): A = F.mappend(value, a2) } object MonoidOp{ implicit def toMonoidOp[A: Monoid](a: A): MonoidOp[A] = new MonoidOp[A]{ val F = implicitly[Monoid[A]] val value = a } } 

I have defined a function (just for the sake of it)

def addXY[A: Monoid](x: A, y: A): A = x |+| y 

I want to lift it so that it could be used using Containers like Option, List, etc. But when I do this

def addXYOptioned = Functor[Option].lift(addXY) 

It says error: could not find implicit value for evidence parameter of type scalaz.Monoid[A] def addOptioned = Functor[Option].lift(addXY)

How to lift such functions?

1
  • Two things: (1) Your function takes two arguments instead of one (strictly speaking it has two argument lists, since the context bound is an implicit parameter). (2) I don't think it is possible to use context bounds with functors, see also stackoverflow.com/questions/10849142/…. Commented Jul 11, 2016 at 8:06

1 Answer 1

0

Your method addXY needs a Monoid[A] but there is no Monoid[A] in scope when used in addXYOptioned, so you also need to add the Monoid constraint to addXYOptioned.

The next problem is that Functor.lift only lifts a function A => B, but we can use Apply.lift2 to lift a function (A, B) => C.

Using the Monoid from Scalaz itself :

import scalaz._, Scalaz._ def addXY[A: Monoid](x: A, y: A): A = x |+| y def addXYOptioned[A: Monoid] = Apply[Option].lift2(addXY[A] _) 

We could generalize addXYOptioned to make it possible to lift addXY into any type constructor with an Apply instance :

def addXYApply[F[_]: Apply, A: Monoid] = Apply[F].lift2(addXY[A] _) addXYApply[List, Int].apply(List(1,2), List(3,4)) // List[Int] = List(4, 5, 5, 6) addXYApply[Option, Int].apply(1.some, 2.some) // Option[Int] = Some(3) 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.