Why is "free" a monad when F is a functor in Free [F [_], A]

From my point of view, if Foo is a monad, then this can also be proven to be a functor. However, I don't understand why in a free monad, if F is a functor, Free in Free [F [_], A] is a monad, so we can use a monadic operation to compose codes.

The question comes up when I read this blog http://underscore.io/blog/posts/2015/04/14/free-monads-are-simple.html

In scalass, Coyoneda uses a type class to represent Functor.

type Functor = Coyoneda[Action, A]

      

therefore, if the Coyoneda implementation is implemented, Free [Functor, A] is a monad.

Here is the code I wrote for simple code. It works and is pretty cool, so we separate execution and interpretation, but why Free becomes a monad for "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))

      

+3


source to share





All Articles