私はフリーモナドを理解しようとしています。チュートリアルの助けを借りて、私はおもちゃの例を書いていましたが、今はなぜそれがコンパイルされるのかわかりません。ここにあります:フリーモナドインタプリタでこのコードをコンパイルするのはなぜですか?
import cats.free.Free
import cats.instances.all._
import cats.~>
trait Operation[+A]
case class Print(s: String) extends Operation[Unit]
case class Read() extends Operation[String]
object Console {
def print(s: String): Free[Operation, Unit] = Free.liftF(Print(s))
def read: Free[Operation, String] = Free.liftF(Read())
}
object Interpreter extends (Operation ~> Option) {
// why does this compile?
override def apply[A](fa: Operation[A]): Option[A] = fa match {
case Print(s) => Some(println(s))
case Read() => Some(readLine())
}
}
object Main {
def main(args: Array[String]) {
val program = for {
_ <- Console.print("What is your name?")
name <- Console.read
_ <- Console.print(s"Nice to meet you $name")
} yield()
program.foldMap(Interpreter)
}
}
私はInterpreterの適用方法について話しています。 Option [A]を返すはずですが、ここでOption [Unit]とOption [String]を返すことができるので、コンパイルエラーであるはずです。しかし、そうではありません。このコードはコンパイルされ、動作します(ただし、Ideaはエラーであることを示しています)。何故ですか?
UPD:なぜこれはコンパイルされませんか?
def test[A](o: Operation[A]): Option[A] = o match {
case Print(s) => Some(s)
case Read() => Some(Unit)
}
うわー、スカラックは本当にスマートです。ありがとうございました。 –
私はすでに答えを受け入れましたが、私の更新を見ることはできますか? –
私の悪い、申し訳ありません。あなたが悲しんでいるように機能します。私は更新を削除しました。 –