次のコードは論文 (RO Bjarnason, Stackless Scala With Free Monads) から改作されています。
この論文のタイトルは、提案されたデータ構造の一般的な目的を示しています。それは、一定のスタック空間で再帰処理を可能にし、ユーザーが明確な方法で再帰を表現できるようにすることです。
具体的には、私の目標は、昇順の定数スタック空間での単純なパターン マッチングに基づいて、ペアの不変ツリー (バイナリ ツリー) またはリスト (n-ary-tree) の構造的書き換えを可能にするモナド構造を持つことです。
sealed trait Free[S[+_], +A]{
private case class FlatMap[S[+_], A, +B](
a: Free[S, A],
f: A => Free[S, B]
) extends Free[S, B]
def map[B](f: A => B): Free[S, B] = this.flatMap((a:A) => Done[S, B](f(a)))
def flatMap[B](f: A => Free[S, B]): Free[S, B] = this match {
case FlatMap(a, g) => FlatMap(a, (x: Any) => g(x).flatMap(f))
case x => FlatMap(x, f)
}
@tailrec
final def resume(implicit S: Functor[S]): Either[S[Free[S, A]], A] = {
this match {
case Done(a) => Right(a)
case More(k) => Left(k)
case FlatMap(a, f) => a match {
case Done(a) => f(a).resume
case More(k) => Left(S.map(k)((x)=>x.flatMap(f)))
case FlatMap(b, g) => b.flatMap((x: Any) => g(x).flatMap(f)).resume
}
}
}
}
case class Done[S[+_], +A](a: A) extends Free[S, A]
case class More[S[+_], +A](k: S[Free[S, A]]) extends Free[S,A]
trait Functor[F[+_]] {
def map[A, B](m: F[A])(f: A => B): F[B]
}
type RoseTree[+A] = Free[List, A]
implicit object listFunctor extends Functor[List] {
def map[A, B](a: List[A])(f: A => B) = a.map(f)
}
var tree : Free[List, Int]= More(List(More(List(More(List(Done(1), Done(2))), More(List(Done(3), Done(4))))), More(List(More(List(Done(5), Done(6))), More(List(Done(7), Done(8)))))))
Free を使用した書き換えはどのように行われますか?
パターンマッチャーのフックはどこにありますか? - パターン マッチャーは、昇順で各サブツリー全体に公開する必要があります。
これは for ブロック内で実行できますか?
【質問を編集しました。】