发布于 2018-07-01 14:07:52
立即,注意到隐式函数类型允许我们对Reader进行编码(主要是免费的),但却失去了理解语法的方便性,这是非常简单的。
我认为Odersky在谈到“monad变压器的更好替代方案”时所指的是,隐式函数类型允许您编码一个相当不带样板的自由单体(没有双关意),这是合成一元效果的一种方法。
从以下对语篇的评论 (重点地雷):
我想我们都同意,在将来我们会有非常细粒度的效果系统,所以很多代码在某种程度上都是有效的。但是,最终你的程序的大部分都是用单一结构编写的。结构本身并不告诉您代码有哪些影响;您需要转到相应的类型。 另一方面,每次您引入一个新的效果类别(它可能像“未证明是完全的”一样普遍存在),您需要将您的代码完全重构为一元方案。这意味着您愿意接受(我估计) 10的减速,风险堆叠溢出,非常冗长,并且很难组成您所有的细粒度效果。或您可以自由,这意味着更好的组合,但可能更多的样板。我可以看到这种工作的意义,你非常有力地告诉你的用户:“不要使用效果,它只是太痛苦”。所以它可以有教育价值。但是如果你必须处理效果,它在几个维度上绝对不是最优的。
在他的论文“隐函数类型的基础”中,欧德斯基提出了一种使用隐式函数类型的可供选择的编码方式,这种编码方式需要更少的样板:
// 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)
https://stackoverflow.com/questions/51114467
复制相似问题