Пересечение нескольких неявных преобразований: изобретать колесо? - PullRequest
36 голосов
/ 23 марта 2012

Хорошо, честное предупреждение: это продолжение моего смешного вопроса с прошлой недели.Хотя я думаю, что этот вопрос не такой смешной.В любом случае, вот что:

Предыдущий нелепый вопрос:

Предположим, у меня есть базовая черта T с подклассами A, B и C, я могу объявить коллекцию Seq[T] например, который может содержать значения типа A, B и C.Чтобы сделать подтип более явным, давайте используем синтаксис привязки типа Seq[_ <: T].

Теперь вместо этого предположим, что у меня есть класс типов TC[_] с членами A, B и C (где "member"означает, что компилятор может найти некоторые TC[A] и т. д. в неявном объеме).Как и выше, я хочу объявить коллекцию типа Seq[_ : TC] с использованием синтаксиса с привязкой к контексту.

Это недопустимо в Scala, и попытка эмуляции может заставить вас почувствовать себя плохим человеком .Помните, что связанный с контекстом синтаксис (при правильном использовании!) Десагарсирует в неявный список параметров для определяемого класса или метода, который здесь не имеет никакого смысла.

Новая предпосылка:

Итакдавайте предположим, что экземпляры класса типов (т.е. неявные значения) исключены, и вместо этого нам нужно использовать неявные преобразования в этом случае.У меня есть тип V («v» означает «view», «fwiw») и неявные преобразования в области A => V, B => V и C => V.Теперь я могу заполнить Seq[V], несмотря на то, что A, B и C никак не связаны.

Но что, если я хочу, чтобы набор вещей, которые были неявно преобразованы в представления V1и V2?Я не могу сказать Seq[V1 with V2], потому что мои неявные преобразования таким образом магически не агрегируют.

Пересечение неявных преобразований?

Я решил свою проблему следующим образом:

// a sort of product or intersection, basically identical to Tuple2
final class &[A, B](val a: A, val b: B)

// implicit conversions from the product to its member types
implicit def productToA[A, B](ab: A & B): A = ab.a
implicit def productToB[A, B](ab: A & B): B = ab.b

// implicit conversion from A to (V1 & V2)
implicit def viewsToProduct[A, V1, V2](a: A)(implicit v1: A => V1, v2: A => V2) =
  new &(v1(a), v2(a))

Теперь я могу написать Seq[V1 & V2] как босс.Например:

trait Foo { def foo: String }
trait Bar { def bar: String }

implicit def stringFoo(a: String) = new Foo { def foo = a + " sf" }
implicit def stringBar(a: String) = new Bar { def bar = a + " sb" }
implicit def intFoo(a: Int) = new Foo { def foo = a.toString + " if" }
implicit def intBar(a: Int) = new Bar { def bar = a.toString + " ib" }

val s1 = Seq[Foo & Bar]("hoho", 1)
val s2 = s1 flatMap (ab => Seq(ab.foo, ab.bar))
// equal to Seq("hoho sf", "hoho sb", "1 if", "1 ib")

При заполнении последовательности происходят неявные преобразования из String и Int в тип Foo & Bar, а затем неявные преобразования из Foo & Bar в Foo и Bar происходит при вызове foobar.foo и foobar.bar.

Текущий нелепый вопрос (-ы):

  1. Кто-нибудь когда-либо реализовывал этот шаблон раньше или я первый идиот?сделать это?
  2. Есть ли гораздо более простой способ сделать это, что я слепо пропустил?
  3. Если нет, то как бы я реализовал более общие слесарные работы, чтобы я мог написать Seq[Foo & Bar & Baz]?Это похоже на работу для HList ...
  4. Дополнительный мега-комбо-бонус: при реализации более общего слесарного дела, могу ли я ограничить типы, чтобы они были уникальными?Например, я хотел бы запретить Seq[Foo & Foo].

Приложение неудач:

Моя последняя попытка (суть) .Не страшно, но мне там не нравятся две вещи:

  • Синтаксис Seq[All[A :: B :: C :: HNil]] (я хочу, чтобы материал HList был непрозрачным, и предпочел бы Seq[A & B & C])
  • Явная аннотация типа (abc[A].a), необходимая для преобразования.Похоже, что вы можете иметь как вывод типа, так и неявные преобразования, но не оба ... Во всяком случае, я не мог понять, как этого избежать.

1 Ответ

1 голос
/ 08 мая 2012

Я могу дать частичный ответ по пункту 4. Это можно получить, применив методику, такую ​​как:

http://vpatryshev.blogspot.com/2012/03/miles-sabins-type-negation-in-practice.html

...