2016-07-11 17 views
0

Только что начал изучать Скалаз. Вот мой кодПоднятие функции, которая принимает неявный параметр с помощью функтора (Scalaz7)

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 

Я хочу, чтобы поднять его так, чтобы его можно было использовать с помощью контейнеров, как опция, 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)

Как поднять такое удовольствие ctions?

+0

две вещи: (1) Ваша функция принимает два аргумента вместо одного (строго говоря, он имеет два списка аргументов, так как граница контекста является неявным параметром). (2) Я не думаю, что можно использовать границы контекста с функторами, см. Также http://stackoverflow.com/questions/10849142/how-can-scalaz-functor-be-given-a-higher-kinded- тип-с-контекстом переплета. – devkat

ответ

0

Вашего метод addXY нужен Monoid[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) 

 Смежные вопросы

  • Нет связанных вопросов^_^