我想了解免费单子。所以在教程的帮助下,我写了一个玩具的例子,现在我不明白它为什么编译。这里是:为什么此代码与免费的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)
}
哇,斯卡拉克真的很聪明。谢谢。 –
我已经接受了答案,但你能看看我的更新吗? –
我的不好,抱歉。它会像你悲伤一样工作。我删除了更新。 –