Я пытаюсь использовать бесформенные создать функцию poly2, которая может принять копроизведение:Копроизведение с Поли
case class IndexedItem(
item1: Item1,
item2: Item2,
item3: Item3
)
case class Item1(name: Int)
case class Item2()
case class Item3()
object IndexUpdater {
type Indexable = Item1 :+: Item2 :+: Item3 :+: CNil
object updateCopy extends Poly2 {
implicit def caseItem1 = at[IndexedItem, Item1] { (a, b) => a.copy(item1 = b) }
implicit def caseItem2 = at[IndexedItem, Item2] { (a, b) => a.copy(item2 = b) }
implicit def caseItem3 = at[IndexedItem, Item3] { (a, b) => a.copy(item3 = b) }
}
def mergeWithExisting(existing: IndexedItem, item: Indexable): IndexedItem = {
updateCopy(existing, item)
}
}
Это дает мне ошибку
Error:(48, 15) could not find implicit value for parameter cse: shapeless.poly.Case[samples.IndexUpdater.updateCopy.type,shapeless.::[samples.IndexedItem,shapeless.::[samples.IndexUpdater.Indexable,shapeless.HNil]]] updateCopy(existing, item)
который я думаю, имеет смысл, учитывая что Poly2 работает с экземплярами предметов, а не с расширенным видом сопроцессора (т. е. импликации генерируются для Item1
, а не Indexable
)
Тем не менее, если не применять poly2 с перегрузкой PolyApply, а вместо этого сделать:
def mergeWithExisting(existing: IndexedItem, item: Indexable): IndexedItem = {
item.foldLeft(existing)(updateCopy)
}
Затем он работает. Я не уверен, что делает foldleft, чтобы типы разрешались. Если это общепринятый способ, как мне сделать это общее, чтобы я мог использовать Poly3? или Poly4?
Есть ли способ расширить тип в поли, чтобы заставить это работать с методом apply? Может быть, я буду об этом неправильно, я открыт для предложений