case class Tell[W, A](w: W, a: A) { def map[B](f: A => B) = Tell(w, f(a)) } def tell[W](w: W): Writer[W, Unit] = Free.lift[[T] = Tell[W, T], Unit](Tell(w, ())) implicit def tellFunctor[W] = new Functor[[A] = Tell[W, A]] { def map[A, B](fa: Tell[W, A])(f: A => B): Tell[W, B] = fa.map(f) } implicit def writerFunctor[W] = new Functor[[A] = Writer[W, A]] { def map[A, B](fa: Writer[W, A])(f: A => B): Writer[W, B] = fa.map(f) } def runAsList[W, A](free: Writer[W, A]): (List[W], A) = free match { case pure: Free.Pure[({type F[T] = Tell[W, T]})#F, A] => (Nil, pure.a) case impure: Free.Impure[({type F[T] = Tell[W, T]})#F, A] => runAsList(impure.ff.a) match { case (ws, a) => (impure.ff.w :: ws, a) } } val e = for { _ <- tell("hoge") _ <- tell("fuga") } yield () runAsList(e) // (List(hoge, fuga),())