I find the following snippet of code (not actual production code but similar) very useful:
implicit class AnyExtensions[A](val x: A) extends AnyVal {
def to[B](implicit f: B => A): B = f(x)
}
In my personal code, this is the only way I allow an implicit def
to implicitly convert a type A
to type B
i.e. by explicitly calling foo.to[Bar]
(implicit classes are allowed for extensions/typeclasses).
This comes in handy in several ways and makes the codebase consistent and pleasant to read:
-
I have replaced all usages of
.toString
with.to[String]
using aShow
typeclass -
We can convert between various collections in a consistent way e.g.
list.to[Vector]
instead oflist.toVector
(this currently already exists in standard library viaCanBuildFrom
but I have extended it to support Java collections too.) -
Convert between the various Java date/time classes e.g.
sqlDate.to[java.time.LocalDate]
-
HKTs are supported too e.g.
sequenceOfTuple2s.to[Map]
instead ofsequenceOfTuple2s.toMap
- cleaner library since currently.toMap
is defined on the collections. -
Various String parsing utils e.g.
string.to[Int]
instead ofstring.toInt
-
string.to[LocalDate]
instead ofLocaldate.parse(string)
etc. using aRead
typeclass. -
Seamless converting to/from Java e.g.
scalaList.to[java.util.ArrayList]
orjavaList.to[mutable.List]
. -
I have
.tryTo
also which wraps the.to
in aTry
e.g.string.tryTo[Int]
I propose building this special converter into the Scala language (needs to be in language or atleast macro-land to support HKT-to-HKT cleanly) and making .to
the only way to summon an implicit def
.