0

刚开始学习Scalaz。这是我的代码

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
    }
}

我已经定义了一个函数(只是为了它)

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

我想抬起它,以便可以使用 Option、List 等容器来使用它。但是当我这样做时

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

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

如何解除这些功能?

4

1 回答 1

0

您的方法addXY需要 aMonoid[A]但在使用时没有Monoid[A]范围addXYOptioned,因此您还需要将Monoid约束添加到addXYOptioned.

下一个问题是Functor.lift只提升一个函数A => B,但我们可以使用Apply.lift2提升一个函数(A, B) => C

使用Monoid来自 Scalaz 本身:

import scalaz._, Scalaz._

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

def addXYOptioned[A: Monoid] = Apply[Option].lift2(addXY[A] _)

我们可以泛化addXYOptioned以使得可以使用实例提升addXY到任何类型的构造函数:Apply

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)
于 2016-07-11T08:42:20.137 回答