想象一个
EvalOption
类型定义如下:
type EvalOption = [A] =>> Eval[Option[A]]
是否有可能以维护 Eval 堆栈安全的方式创建 Monad 实例?
我能够为这种类型创建一个 Applicative 实例,但是我在实现
flatMap
方法时遇到了问题。所以,如果有人知道这样做的方法,我将非常感激😄。
谢谢,祝你玩得愉快!
是的,有可能:
import cats.Monad
import cats.data.Eval
import cats.implicits._
type EvalOption[A] = Eval[Option[A]]
implicit val evalOptionMonad: Monad[EvalOption] = new Monad[EvalOption] {
def pure[A](x: A): EvalOption[A] = Eval.now(Option(x))
def flatMap[A, B](fa: EvalOption[A])(f: A => EvalOption[B]): EvalOption[B] =
Eval.defer {
fa.flatMap {
case Some(a) => f(a)
case None => Eval.now(None)
}
}
}
在
flatMap
方法中,我们将整个计算包装在 Eval.defer
中,这确保了 flatMap
计算不会被急切地评估。这意味着每个 flatMap
操作都被评估为一个单独的 Eval
,从而保持堆栈安全。