Неявна естествена трансформация на Scala с монада, която не успява да намери функции за разбиране

Кодът, който имам, е следният:

class SourceService[Out[+_]](implicit monad:Monad[Out]) {
  def doSomething:Out[String] =
    monad.point("Result")
}

class SimplifiedPipe[Out[+_], In[+_]]
  (myService:SourceService[In])
  (implicit monad:Monad[Out], pipe: ~>[In, Out]) {

  implicit def ~>[I[+ _], O[+ _], T](value: I[T])(implicit nt: ~>[I, O]): O[T]
  = nt.apply(value)

  implicit class lift[T, O[+ _]](m: O[T])(implicit monad: Monad[O]) {
    def flatMap[S](f: T => O[S]): O[S] =
      monad.bind(m)(f)

    def map[S](f: T => S): O[S] =
      monad.map(m)(f)

    def foreach(f: T => Unit) =
      monad.map(m)(f)
  }

  def run: Out[String] =
    for {
      s <- myService.doSomething
    } yield s
}

И intellij разпознава имплицитите, при компилиране не може да разреши функцията map. Нещо, което очевидно правя нередно тук?


person J Pullar    schedule 09.04.2015    source източник
comment
Накратко, някаква причина да не искате просто да приложите pipe изрично? Освен това не бих се учудил, ако ковариацията ви навличаше в проблеми.   -  person Travis Brown    schedule 09.04.2015
comment
Определено вариант. В момента използвам имплицитно тръбопроводи и обвързвам изрично. Все пак е добре да разберем дали може да работи или защо не. Ковариацията между двете имплицитни стойности може да е причина за проблема?   -  person J Pullar    schedule 09.04.2015
comment
Направи типовете от по-висок род инвариантни. Нямаше разлика.   -  person J Pullar    schedule 10.04.2015


Отговори (1)


Успях да разреша това, като създадох персонализиран комбиниран имплицитен клас. Също така това работи, докато import scalaz._ НЕ е в обхвата.

implicit class PipeMonad[Out[+_], In[+_], A](in: In[A])(implicit monad: Monad[Out], pipe:In ~> Out) {
  def flatMap[T](f:A => Out[T]):Out[T] =
    monad.bind(pipe(in))(f)
  def map[T](f:A => T):Out[T] =
    monad.map(pipe(in))(f)
}
person J Pullar    schedule 23.04.2015