Action を Future にマップするために scalaz.Free を使用する例を 1 つ書きました。しかし、私はその利点を理解しようとしています。ここで答えが得られることを願っています。ここに私のコードスニペットがあります
まず、AST であるアクションを作成します。
trait Action[A]
case class GetNumberAction(x: Int) extends Action[Int]
case class GetStringAction(x: String) extends Action[String]
case class ConvertToIntAction(x: String) extends Action[Int]
case class AddAction(x: Int, y: Int) extends Action[Int]
次に、Scalaz Free と Coyonda を使用して Action を ASTMonad にマップするクラスを作成します。
type Functor[A] = Coyoneda[Action, A]
type ASTMonad[A]= Free[Functor, A]
def toMonad[A](action: Action[A]): ASTMonad[A] = Free.liftFC[Action, A](action)
object ADTMonad {
def getNumber(x: Int): ASTMonad[Int] = toMonad(GetNumberAction(x))
def getString(x: String): ASTMonad[String] = toMonad(GetStringAction(x))
def converToInt(x: String): ASTMonad[Int] = toMonad(ConvertToIntAction(x))
def add(x: Int, y: Int): ASTMonad[Int] = toMonad(AddAction(x, y))
}
最後に、Action を Future に解釈する Interpreter を作成します。
object Interpreter extends (Action ~> Future) {
def apply[A](action: Action[A]): Future[A] = {
action match {
case GetNumberAction(x) => Future(x)
case GetStringAction(x) => Future(x)
case ConvertToIntAction(x) => Future(x.toInt)
case AddAction(x, y) => Future(x + y)
}
}
}
実行すると、使用できます
val chain = for {
number <- ASTMonad.getNumber(x)
str <- ASTMonad.getString(y)
convertedNumber <- ASTMonad.converToInt(str)
total <- ASTMonad.add(number, convertedNumber)
} yield total
chain.runWith(Interpreter)
それは機能しているようで、このモナドとインタープリターのことを理解していると思います。ただし、 Future.flatmapとmapを直接使用している場合、ソリューションと比較してどのような利点があると考えていますか?
for {
number <- Future(x)
str <- Future(y)
convertedNumber <- Future(str.toInt)
total <- Future(number + convertedNumber)
} yield total
Future flatmap と map を使用するコードは、私には単純に見えます。私の質問に戻りますが、Future はすでに flatMap と map を提供しているので、Free モナドを使用してビジネス ロジックを Future に解釈する必要がありますか。もしそうなら、誰かが私にもっと具体的な例を教えてくれるので、その利点を見ることができますか?
前もって感謝します