Sunday, November 22, 2009

Type aliasing and implicit conversions in harmony

This topic combines advanced two topics. types and implicit methods. This topic is not really intended to be instructional as much as a illustration of the cool stuff you can do with the language. As always becareful not to cut yourself :-)

In keeping with the uniform principle of Scala, types can defined as variables. This is useful for several reasons but this topic covers a cool/fun effect of having types be declared like variables. Type Aliasing. In the example below an alias | is created for the Either class. This allows the | to be used in place of Either.
  1. // Start of example 1.  creating the type alias
  2. // define the | type
  3. scala> type |[A,B] = Either[A,B]
  4. defined type alias $bar
  5. // If a Type has 2 parameters it can be used in operator form
  6. scala> Array[Int | Long](Left(5),Right(12L))
  7. res0: Array[|[Int,Long]] = Array(Left(5), Right(12))
  8. // start of example 2.  Simplify creation of an Array (or other collection) of either
  9. scala> implicit def makeLeft[A,B](a:A):Either[A,B] = Left(a)
  10. makeLeft: [A,B](a: A)Either[A,B]
  11. scala> implicit def makeRight[A,B](b:B):Either[A,B] = Right(b) 
  12. makeRight: [A,B](b: B)Either[A,B]
  13. // Since there are implicits to convert to Right and Left the values in the Array will be wrapped
  14. // automatically.  Makes the syntax MUCH cleaner and easier to read.
  15. scala> Array[Int|String](5,"Wurst",123,2,6)
  16. res1: Array[|[Int,String]] = Array(Left(5), Right(Wurst), Left(123), Left(2), Left(6))


  1. I do wonder why the makeLeft and makeRight implicits did not cause an ambiguity error. After all, what's to say Int is the left and String is the right?

  2. The information that determines if the value is a Left or a Right is inferred from the Array type signature: Array[Int | String] the type inferencer is able to determine that the string is the Right and vice versa. Pretty powerful.

  3. I wouldn't necessarily call this type inferencing. As far as I understand implicit conversions. Since 5 is not of type Either[Int|String], it will look for implicits before aborting with a compile error. It will find the that the only implicit which takes in the right argument (both in this case) and the produces the correct type is makeLeft (because makeRight would produce Either[String|Int], not Either[Int, String]. Symetrically for any String argument in the Array constructor.

    There is absolutely not ambiguity as far as I am concerned and this all naturally occurs from following the simple implicit conversion rules, I wouldn't exactly consider this behaviour to be type inferencing.

    Nice post btw, do any of you have any ideas on why makeLeft and makeRight are not part of "language.implicitConversions"?