Scala захватить все последствия объема вызова?
Предположим, у меня есть область A
в котором определены неявные значения и блок кода c
который использует эти неявные значения. У меня тоже есть сфера B
который имеет последствия совместимого типа, так что если я скопирую блок кода c
в B
, он будет компилироваться и запускаться без проблем. Это безобразно, конечно, так как я дублирую c
в двух местах, поэтому я хотел бы переехать c
в свою собственную функцию. Теперь функция подписи c
должен выглядеть так:
def c(args...)(implicit implicitArgs...) = ...
где implicitArgs
неявные значения, используемые в c
, Учитывая, что некоторые фреймворки (в моем случае Scalding) определяют множество последствий, подпись здесь может быстро выйти из-под контроля. Есть ли синтаксис, чтобы сказать "нести все неявные значения в вызывающей области"? Или есть умный способ обойти это?
ура, Джефф
2 ответа
Я нашел способ "неявных аргументов карри":
def myfunc(arg:Something)(implicit session:Otherthing):Unit = ....
val curriedFunc = myfunc(value)(_:Otherthing)
curriedFunc(valueOfOtherThing)
Для получения дополнительной информации см. Частичные элементы без каррирования по адресу http://www.codecommit.com/blog/scala/function-currying-in-scala
Примечание: я новичок в Scala и не знаю всех лучших практик.
Не уверен, что это сработает, но вы можете попробовать. Вы можете сгруппировать импликации в контейнерные объекты.
Пример: допустим, у вас есть последствия типа X
, Y
а также Z
и вы не всегда хотите добавить три implicit
аргументы для каждого метода. Допустим, вы определили объект контейнера для них:
class MyImplicits(val x:X, val y:Y, val z:Z)
Для того, чтобы позволить автоматическое создание MyImplicits
Оболочка, вы создаете метод объекта, который выводит его из отдельных последствий. Точно так же вы определяете неявные методы без оболочки:
object MyImplicits {
implicit def wrap(implicit x:X, y:Y, z:Z):MyImplicits = new MyImplicits(x, y, z)
implicit def unwrapX(implicit wrapper:MyImplicits):X = wrapper.x
implicit def unwrapY(implicit wrapper:MyImplicits):Y = wrapper.y
implicit def unwrapZ(implicit wrapper:MyImplicits):Z = wrapper.z
}
Допустим, у нас есть такой метод:
def foo(...)(implicit implicits:MyImplicits) = ...
Следующее должно работать:
implicit val implicitXIsInScope:X = ...
implicit val implicitXIsInScope:Y = ...
implicit val implicitXIsInScope:Z = ...
foo(...) // MyImplicits should automatically be created
Аналогично, если экземпляр MyImplicits
находится в неявной области видимости, вы должны иметь возможность вызывать любой метод, который требует неявного экземпляра X
без необходимости развернуть его явно.
Я не пробовал это все же. Пожалуйста, дайте мне знать, если это работает!