2016-07-30 4 views
1

В этом фрагменте y.run не отображается тип.Монад-трансформаторы со сказовыми потоками

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 
} 

Компилятор показывает эту ошибку:

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

Должен ли я создать Catchable экземпляр для StateStringTask? Как мне это сделать? Или есть более простой способ обработки эффектов с состоянием при запуске Process?

ответ

0

Я предполагаю, что это не является оптимальным, но я получил его, сделав StateStringTask экземпляр Catchable:

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

Для талейStateT на Process с Task как эффект. Например:

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