Andriy Polishchuk (isorecursive) wrote,
Andriy Polishchuk
isorecursive

Scala: Call-by-Need

Во время дискуссии пришла идея, как на имплицит-конверсиях реализовать call-by-need:
class ~>[A](delayed: => A) {
  private lazy val value = delayed  
  def force() = value
}

implicit def thunkable[A](computation: => A)  =
  new ~>(computation)

implicit def forceable[A](computation: ~>[A]) =
  computation.force

def lazyInR(x: Int, y: ~>[Int]) = {
  val a = x + 5 * y
  val b = y - 5 * x
  a * b
}

def x: Int = {
  println("I'm printed once!");
  2
}

lazyInR(1, x)

http://www.scalakata.com/509aafece4b093f3524f3a1b

Идея состоит в том, чтобы, подобно встроенному функционалу для by-name, требовать для call-by-need вычислений пометки в сигнатуре типа стрелочкой, только не =>, а ~>, которую мы реализуем классом. Это даёт возможность написать имплицит-конверсии из передаваемого по факту в функцию A в ~>[A] (для задержки), и обратно (для форсирования). В первой конверсии и в конструкторе класса A будет задерживаться by-name благодаря =>. Вторая конверсия - из ~>[A] в A, и она состоит просто в вызове метода force, который содержит логику мемоизированного by-name.

Updated:
Более интересный пример с call-by-need списками: http://www.scalakata.com/509ab47ce4b093f3524f3a24
Tags: call-by-need, implicits, lazy, scala
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 3 comments
Спасибо, хороший текст. Я тоже типа баловался, но у меня типа как-то слишком глобально вышло.

https://github.com/vpatryshev/ScalaKittens/blob/master/src/main/scala/scalakittens/Caching.scala

На эту тему ещё Киселёв сказал, что речь идёт о state continuation monad.
@ .../Caching.scala
О, ну это явно интереснее в плане реального использования для кеширования.

@ На эту тему ещё Киселёв сказал, что речь идёт о state continuation monad.
Звучит увлекательно. Это же оно?: http://zwizwa.be/-/meta/20110117-141622
Да, оно. Я ещё не изучал (не скалифицировал); идея-то понятна, интересны детали.