2016-07-30 11 views
1

In diesem Code-Schnipsel y.run wird nicht überprüft.Monad-Transformatoren mit Scalaz-Streams

object Test { 

    type StateStringTask[A] = StateStringT[Task, A] 
    type StateStringT[M[_], A] = StateT[M, String, A] 

    val x: Process[Task, Unit] = ??? 

    val y: Process[StateStringTask, Unit] = ??? 

    x.run // This typechecks 

    y.run // This fails 
} 

Der Compiler zeigt diesen Fehler:

could not find implicit value for parameter C: scalaz.Catchable[[x]Test.StateStringTask[x]]

Habe ich eine Catchable Instanz für StateStringTask zu schaffen haben? Wie mache ich das? Oder gibt es eine einfachere Möglichkeit, stateful Effekte zu behandeln, wenn Sie eine Process ausführen?

Antwort

0

Ich denke, das ist nicht optimal, aber ich habe es von StateStringTask eine Instanz von Catchable machen:

implicit val stateStringTaskInstance: Catchable[StateStringTask] = 
    new Catchable[StateStringTask] { 
    // `a.attempt` stackoverflows, don't ask me why :) 
    def attempt[A](a: StateStringTask[A]): StateStringTask[Throwable \/ A] = a >>= (
     x => Catchable[Task].attempt(Applicative[Task].pure(x)).liftM[StateStringT] 
    ) 
    def fail[A](err: Throwable) = Catchable[Task].fail(err).liftM[StateStringT] 
    } 

Um hissen die StateT auf einem Process mit einem Task als Wirkung. Zum Beispiel:

def received(queue: Queue[Event]): Process[StateStringTask, Event] = { 
    val toStateStringTask = new (Task ~> StateStringTask) { 
     def apply[A](t: Task[A]): StateStringTask[A] = t.liftM[StateStringT] 
    } 
    // queue.dequeue: Process[Task, Event] 
    queue.dequeue.translate(toStateStringTask) 
    }