据我了解,如果 Foo 是单子,那么它也可以被证明是函子。但是,我不明白为什么在 free monad 中,如果 F 是 functor,Free[F[_], A] 中的 Free 是 monad,所以我们可以使用 monadic 操作来编写代码。
当我阅读此博客http://underscore.io/blog/posts/2015/04/14/free-monads-are-simple.html时提出了这个问题
在 scalaz 中,Coyoneda 使用类型类来呈现 Functor。
type Functor = Coyoneda[Action, A]
因此,如果提供 Coyoneda 实现,则 Free[Functor, A] 是 monad。
这是我为简单代码编写的代码。它工作得很好而且很酷,所以我们将执行和解释器分开,但是为什么 Free 变成了“免费”的单子
//data type
sealed trait Action[A]
case class IntOption(number: Int) extends Action[Int]
//implements functor, AKA interpretor
type ScriptImpl[A] = Coyoneda[Action, A]
object Interpreter extends (Action ~> Option) {
override def apply[A](a: Action[A]): Option[A] = {
a match {
case IntOption(t) => Option(t)
}
}
}
//lift to free monad
def toFree[A](a: Action[A]): Free[ScriptImpl, A] = Free.liftFC[Action, A](a)
val result: Free[ScriptImpl, Int] = for {
a <- toFree(IntOption(1))
b <- toFree(IntOption(2))
c <- toFree(IntOption(3))
} yield {
a + b + c
}
println(Free.runFC(result)(Interpreter))