Danny Navarro Danny Navarro - 11 months ago 90
Scala Question

Monad transformers with scalaz-streams

In this snippet

doesn't typecheck.

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

The compiler shows this error:

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

Do I have to create a
instance for
? How do I do that? Or is there an easier way to handle stateful effects when running a

Answer Source

I guess this is suboptimal but I got it by making StateStringTask an instance of 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]

To hoist the StateT on a Process with aTask as effect. For example:

  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]