立刻,最简单的是注意到隐式函数类型使我们能够对Reader monad进行编码,而该monad主要是自由分配的,但是却失去了理解语法的便利性。
我认为Odersky在谈到“更好的替代monad转换器”时所指的是,隐式函数类型使您可以编码相当简单的自由monad(无双关),这是构成monadic效果的一种方法。 。
来自以下关于话语的评论(重点是我的话):
我猜我们俩都同意,将来我们将拥有非常精细的效果系统,以至于很多代码以某种方式有效。但是随后,您最终会以Monad结构编写程序的大部分内容。结构本身不会告诉您代码具有什么作用;您需要转到该类型。
另一方面,每次引入一个新的效果类别(它可能像“未证明是完全的”一样普遍存在)时,您需要将代码完全重构为monadic方案。这意味着您愿意(我估计)减慢10,冒着堆栈溢出的风险,非常冗长,并且很难组合所有细粒度的效果。否则,你就自由了,这意味着更好的构图,但可能会更多。在您非常有力地告诉您的用户的意义上,我可以看到这项工作:“不要使用效果,太痛苦了”。因此它可能具有教育价值。但是,如果您必须处理效果,那么它在几个方面就完全不是最佳选择。
在他的论文《隐式函数类型的基础》中,Odersky提出了一种使用隐式函数类型对自由monad进行编码的替代方法,该方法需要更少的样板代码:
// Free definition
type FreeIFT[A[_], M[_], T] = implicit Natural[A, M] => implicit Monad[M] => M[T]
// GADT defintion
enum KVStoreB[T] {
case Put(key: String, value: Int) extends KVStoreB[Unit]
case Get(key: String) extends KVStoreB[Option[Int]]
}
// Lifted definition
import KVStoreB._
type KVStoreIFT[M[_], T] = FreeIFT[KVStoreB, M, T]
def iftExpr[M[_]]: KVStoreIFT[M, Option[Int]] =
for {
_ <- Put("foo", 2).lift
_ <- Put("bar", 5).lift
n <- Get("foo").lift
} yield n
// Free interpeter
def iftInterpreter = new Natural[KVStoreB, Future] {
def apply[T](fa: KVStoreB[T]): Future[T] = ???
}
// Running the interpreter over the free structure
val iftOutput: Future[Option[Int]] = iftExpr[Future](iftInterpreter)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句