2016-07-11 7 views
0

Scalaz를 처음 배우기 시작했습니다. 여기가 옵션, 목록 등 같은 컨테이너를 사용하여 사용할 수 있도록 내가 그것을 들어 올려 싶어 내가 (그냥를 위해) 함수를 정의Functor (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 

입니다 . 그러나 나는이

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? Monoid[A]을 필요로하지만, addXYOptioned에 사용되는, 그래서 당신은 또한 addXYOptionedMonoid 제약 조건을 추가 할 때 범위에는 Monoid[A] 없다 addXY

+0

두 가지 : (1) 함수는 하나가 아닌 두 개의 인수를 취합니다 (엄격하게 말하면 두 개의 인수 목록이 있습니다. 경계 바운드는 암시 적 매개 변수이므로). (2) 나는 펑터와 컨텍스트 경계를 사용할 수 있다고 생각하지 않는다. http://stackoverflow.com/questions/10849142/how-can-scalaz-functor-be-given-a-higher-kinded- type-with-a context-bound를 사용합니다. – devkat

답변

0

귀하의 방법.

다음 문제는 Functor.lift이 기능 A => B 만 들어 올리는 것입니다. 그러나 의 기능을 사용하려면 Apply.lift2을 사용할 수 있습니다.

사용 Scalaz 자체에서 Monoid :

import scalaz._, Scalaz._ 

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

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

우리는 그것이 가능 Apply 인스턴스와 모든 종류의 생성자에 addXY를 들어 올릴 수 있도록 addXYOptioned을 일반화 수 :

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)