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 без необходимости развернуть его явно.

Я не пробовал это все же. Пожалуйста, дайте мне знать, если это работает!

Другие вопросы по тегам