catsでは、Monad
形質を使用してモナドを作成する場合、メソッドtailRecM
の実装を提供する必要があります。猫:Monadsの非テール再帰的tailRecMメソッド
私はtailRecM
sealed trait Tree[+A]
final case class Branch[A](left: Tree[A], right: Tree[A]) extends Tree[A]
final case class Leaf[A](value: A) extends Tree[A]
implicit val treeMonad = new Monad[Tree] {
override def pure[A](value: A): Tree[A] = Leaf(value)
override def flatMap[A, B](initial: Tree[A])(func: A => Tree[B]): Tree[B] =
initial match {
case Branch(l, r) => Branch(flatMap(l)(func), flatMap(r)(func))
case Leaf(value) => func(value)
}
//@tailrec
override def tailRecM[A, B](a: A)(func: (A) => Tree[Either[A, B]]): Tree[B] = {
func(a) match {
case Branch(l, r) =>
Branch(
flatMap(l) {
case Right(l) => pure(l)
case Left(l) => tailRecM(l)(func)
},
flatMap(r){
case Right(r) => pure(r)
case Left(r) => tailRecM(r)(func)
}
)
case Leaf(Left(value)) => tailRecM(value)(func)
case Leaf(Right(value)) => Leaf(value)
}
}
}
1の尾再帰実装を提供することができないという以下のシナリオを発見した)は、上記の例によれば、どのようにこのtailRecM
方法は、flatMap
メソッド呼び出しを最適化するために使用することができますか? flatMap
メソッドの実装は、コンパイル時にtailRecM
によってオーバーライド/変更されますか?
2)tailRecM
が上記のように末尾再帰型でない場合でも、元のflatMap
メソッドを使用するより効率的ですか?
あなたの考えをお伝えください。
ありがとうございました。私はあなたが私の2番目の質問に答えたと思います。最初のことについての任意のアイデア? –
@tharindu_DGがcatsチケットへのリンクを追加しました –