假设我编写了一个依赖于其他解释器的解释器
def interpreter[S[_]](implicit kvs:KVS.ops[S, UUID, String]): Example ~> Free[S, ?]
假设我的解释器想要将事件表面化为一个编写器monad,所以S必须至少是一个编写器monad,或者包含一个writer monad的转换。
有没有惯用的方法呢?
例如,我可以在编写器monad上创建一个免费的Monad包装器来公开write
或tell
等方法。
def interpreter[S[_]](implicit kvs:KVS.ops[S, UUID, String], writer.Writer.ops[S]) = new (Example ~> Free[S, ?]) {
...
case MyMessage() =>
for {
_ <- writer.tell(Vector("My message was called"))
} yield "Complete"
或者我可以使用MonadWriter typeClass for S并使用导入的函数解除空闲?
type MyWriter[S[_]] = MonadWriter[M, Vector[String]]
def interpreter[S[_]:MyWriter](implicit kvs:KVS.ops[S, UUID, String]) = new( Example ~> Free[S, ?]) {
import Writer2FreeOps._
...
case MyMessage() =>
for {
_ <- tell(Vector("My message was called"))
} yield "Complete"
object Writer2FreeOps {
def tell[S[_], W](w:W)(implicit M:MonadWriter[S, W]):Free[S, Unit] =
Free.liftF(M.tell(w))
}
我看到有一个FreeT monad,但我认为这会限制泛型行为,如果你有一个KVS ~> Free[State, UUID, String]
的解释器,另一个验证是KVS ~> FreeT[Xor, State, UUID, String]
,以上示例将限制它可以使用哪一个?或者另一种方式是如果解释器是例子〜> FreeT [作家..],KVS需要从Free [S,?]到FreeT [Writer,S,?]的自然转换,这看起来有点麻烦......