如何在scala中使用隐式函数类型来对效果进行建模?

时间:2018-06-30 11:25:07

标签: scala

隐式函数类型计划在Scala 3.0中使用,claimed用于支持“效果功能”和可组合。它被提出作为monad变压器的更好替代品。但是,进一步阅读explanation似乎只是隐式函数类型只能对Reader monad建模。我想念什么吗?

1 个答案:

答案 0 :(得分:1)

立即注意到,隐式函数类型使我们可以对Reader monad进行编码,而该编码主要是自由分配的,但却失去了理解语法的便利性。

思考奥德斯基在谈到“ monad转换器的更好替代品”时指的是事实,即隐式函数类型允许您编码相当简单的自由monad(无双关语) ),这是构成单调效果的一种方法。

From the following comment on discourse(重点是我):

  

我猜我们俩都同意,将来我们将拥有非常精细的效果系统,以至于很多代码以某种方式有效。但是随后,您最终会用monad结构编写程序的大部分内容。结构本身不会告诉您代码具有什么作用;您需要转到相应的类型。

     

另一方面,每次您引入一个新的效果类别(它可能像“未证明是完全的”一样普遍存在)时,您需要将代码完全重构为monadic方案。这意味着您愿意(我估计)减慢10,冒着堆栈溢出的风险,非常冗长,并且很难构筑所有细粒度的效果。 或者您可以自由活动,这意味着更好的构图,但可能还会有更多样板。在您非常有力地告诉您的用户的意义上,我可以看到这项工作:“不要使用效果,太痛苦了”。因此它可能具有教育价值。但是,如果您必须处理效果,则它在多个维度上都是次优的。

在他的论文Foundations of Implicit Function Types中,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)