This is actually not so bad (see my answer here to a similar question for some further discussion of this approach):
trait Setsifier[I, O] { def apply(i: I): O } object Setsifier { def apply[I, O](f: I => O) = new Setsifier[I, O] { def apply(i: I) = f(i) } implicit def base[I](implicit ev: I <:!< Seq[_]) = apply((_: Seq[I]).toSet) implicit def rec[I, O](implicit s: Setsifier[I, O]) = apply((_: Seq[I]).map(s(_)).toSet) } def setsify[I, O](i: I)(implicit s: Setsifier[I, O]) = s(i)
And then:
scala> println(setsify(Seq(Seq(Seq(Seq(1)), Seq(Seq(2, 3)))))) Set(Set(Set(Set(1)), Set(Set(2, 3))))
Statically printed as Set[Set[Set[Set[[Int]]]] and all.
Well, I lied a little. <:!< above is not in the standard library. However, in Shapeless , or you can very easily define it yourself:
trait <:!<[A, B] implicit def nsub[A, B] : A <:!< B = new <:!<[A, B] {} implicit def nsubAmbig1[A, B >: A] : A <:!< B = sys.error("Don't call this!") implicit def nsubAmbig2[A, B >: A] : A <:!< B = sys.error("Don't call this!")
And thatβs really all.
Travis brown
source share