Кэширование неявного разрешения

Чтобы сократить время компиляции моего проекта, я кэширую определенные классы типов, которые разрешаются неявным поиском. Это кажется несколько громоздким, потому что прямая реализация не работает:

scala> implicit val x: String = implicitly[String]
x: String = null

Неявный поиск рассматривает собственное неинициализированное определение как допустимую реализацию. lazy val взорвет стек с бесконечной рекурсией. Поэтому я сейчас обрабатываю это следующим образом:

implicit val x: String = cache.x

object cache {
   val x: String = implicitly[String]
}

Но это делает его чрезмерно сложным, и определения кэша не могут легко использовать другие классы кэшированных типов (поскольку они не являются неявными).

Кроме того, скрытие самого значения из области видимости, к сожалению, не работает.

scala> :pas
// Entering paste mode (ctrl-D to finish)

object scope {
    implicit val x: String = {
        import scope.{ x => _ }
        implicitly[String]
    }
}

// Exiting paste mode, now interpreting.

defined object scope

scala> scope.x
res0: String = null

Есть ли более элегантный способ добиться кеша неявного разрешения?


person Taig    schedule 21.12.2015    source источник
comment
@Taig Вы смотрели макрос cachedImplicit Shapeless? Это очень похоже тому, что ты делаешь.   -  person Travis Brown    schedule 21.12.2015
comment
@TravisBrown, это именно то, что я искал (и тайно надеялся). Я не сталкивался с этим с моими запросами Google. Если вы переместите свой комментарий в ответ, я буду рад принять.   -  person Taig    schedule 21.12.2015


Ответы (2)


Shapeless предоставляет макрос cachedImplicit с реализация, которая очень похожа на вашу (она использует затенение, чтобы избежать рекурсии, а тот факт, что это макрос, означает использование может быть чище).

Существуют некоторые ограничения, о которых следует помнить, и вы можете не захотеть использовать новую зависимость для этого единственного метода. , но реализация довольно краткая, и это, по крайней мере, хорошая отправная точка.

person Travis Brown    schedule 21.12.2015

Просто для полноты: бесформенный макрос в принятом ответе затмевает собственное определение, чего я не придумал. Поэтому моя конкретная проблема может быть решена следующим образом:

implicit val x: String = {
    def x = ???
    implicitly[String]
}
person Taig    schedule 22.12.2015