June 19th, 2011

glider

имплициты

Недавно прошаривался в скале и нашел несколько интересных статей про имлициты:
* Can someone explain me implicit conversions in Scala? (материал для начального ознакомления с имплицитами)
* Where does Scala looks for implicits? (исчерпывающий материал по поводу видов имплицитов в скале и правил их поиска компилятором)
* Context and view bounds again (использование имплицитов для ограничения генерик-параметров - эмуляция тайпклассов Хаскелла. два подхода, каждый со своими плюсами и минусами)
* Implicit Parameters: Dynamic Scoping with Static Types (научная работа 2000 года, в ней Эрик Мейер с коллегами добавили неявные параметры в Хаскелл. интересно сравнить научное исследование и практическую реализацию, по сути, одной и той же идеи)

Также вот еще три интересных применения имплицитов. Очень мне нравятся, особенно последний. Интересно, как они работают на практике - не будет ли неожиданных сайд-эффектов при их применении в большом проекте. Моя интуиция подсказывает, что здесь уж слишком много магии, но сходу придумать контр-примеры не могу.

Во-первых, оператор пайплайна из F# (оригинальный пост):

implicit def toPipeLink[X](v: X): PipeLink[X] = new PipeLink[X](v)
class PipeLink[X](value: X) {
  def |>[Y](func: X => Y): Y = func(value)
}
Во-вторых, автоматическое каррирование (stackoverflow):

implicit def curryImplicitly[A,B,C](f: (A, B) => C) =
  (a: A) => (b: B) => f(a, b)
implicit def uncurryImplicitly[A,B,C](f: A => B => C) =
  (a: A, b: B) => f(a)(b)
В-третьих, вот способ попросить компилятор искать по всему графу неявных преобразований между типами, а не останавливаться на типах, непосредственно достижимых из текущего (тоже stackoverflow).

implicit def aToB(a: A): B = ... // will convert A to B
implicit def aToB[A1 <% A](a: A1): B = ... // will convert anything, that can be converted to A, to B