带有 scalaz 流的 Monad 转换器
Monad transformers with scalaz-streams
在此代码段中 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]]
我是否必须为 StateStringTask
创建一个 Catchable
实例?我怎么做?或者当 运行 a Process
?
时,是否有更简单的方法来处理有状态效果
我想这是次优的,但我通过使 StateStringTask
成为 Catchable
的实例得到它:
implicit val stateStringTaskInstance: Catchable[StateStringTask] =
new Catchable[StateStringTask] {
// `a.attempt` Whosebugs, 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]
}
要提升 Process
上的StateT
,效果为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)
}
在此代码段中 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]]
我是否必须为 StateStringTask
创建一个 Catchable
实例?我怎么做?或者当 运行 a Process
?
我想这是次优的,但我通过使 StateStringTask
成为 Catchable
的实例得到它:
implicit val stateStringTaskInstance: Catchable[StateStringTask] =
new Catchable[StateStringTask] {
// `a.attempt` Whosebugs, 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]
}
要提升 Process
上的StateT
,效果为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)
}