我想了解免費單子。所以在教程的幫助下,我寫了一個玩具的例子,現在我不明白它爲什麼編譯。這裏是:爲什麼此代碼與免費的monad解釋器編譯?
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)
}
}
我在說解釋器的應用方法。它應該返回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)
}
哇,斯卡拉克真的很聰明。謝謝。 –
我已經接受了答案,但你能看看我的更新嗎? –
我的不好,抱歉。它會像你悲傷一樣工作。我刪除了更新。 –