Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Easy Heterogeneous Varargs in Scala
// Define the general Arg type and companion object:
import language.higherKinds, language.implicitConversions, language.existentials
object Arg { implicit def toArg[Tc[_], T: Tc](t: T): Arg[T, Tc] = Arg(t, implicitly[Tc[T]]) }
case class Arg[T, Tc[_]](value: T, typeclass: Tc[T])
// Say, for example we have a typeclass for getting the length of something, with a few instances
trait Lengthable[T] { def length(t: T): Int }
implicit val intLength = new Lengthable[Int] { def length(i: Int) = 1 }
implicit val stringLength = new Lengthable[String] { def length(s: String) = s.length }
// Now, define our varargs method:
def getLengths(args: (Arg[T, Lengthable] forSome { type T })*) =
args.map { case a: Arg[t, Lengthable] => a.typeclass.length(a.value) }
// Then, here it is being used in user code:
getLengths(1, "foo") // Works
getLengths(123, 'x') // Doesn't work - no `Lengthable` for `Char`
@lolgab

This comment has been minimized.

Copy link

@lolgab lolgab commented Mar 22, 2019

Hi, very nice code, How can I modify it to work with a typeclass taking two parameters? I have a sort of trait Conversion[From, To] typeclass..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment