'SFF8SJUFS
type Writer[W, A] = Free[[T] = Tell[W, T], A]
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 {
_ _ } yield ()
runAsList(e)
// (List(hoge, fuga),())