Showing posts with label type. Show all posts
Showing posts with label type. Show all posts

Tuesday, February 9, 2010

Structural Types: Multiple Methods and Type Aliasing

There are two more aspects related to structural typing that are useful to look at. Structural types with multiple methods and type aliases.

For background on this topic also look at:
Structural Types are not limited to defining a single method. In that regard they are very similar to interfaces without the binary incompatibility issues. However do not be fooled into thinking they are the same thing. For one reason reflection is used so performance can be an issue in certain cases and also interfaces/traits have semantics that structural types do not.
  1. /*
  2. Defining a types that has both a length and charAt method.  
  3. Just a warning.  If you leave off the () after length this will not work.  This is not a bug.  Martin kindly left a comment on why it is not.
  4. */
  5. scala> def foreach(t : {def length():Intdef charAt(i:Int):Char}, f : Char => Unit) = {
  6.      | 0 until t.length foreach {i => f(t.charAt(i))}  
  7.      | }
  8. foreach: (t: AnyRef{def length(): Intdef charAt(i: Int): Char},f: (Char) => Unit)Unit
  9. // A string matches the structural type
  10. scala> foreach ("hello", println _)
  11. h
  12. e
  13. l
  14. l
  15. o

Pretty unexpected I would say. A feature of Scala which complements Structural types are type aliases. They are useful in many situations and one is with use with Structural Types:
  1. /*
  2. With type aliasing you can assign a structural type a name
  3. */
  4. scala> type IChar = {def length():Int
  5.      |               def charAt(i:Int):Char}
  6. defined type alias IChar
  7. scala> def print( t : IChar) = 0 until t.length() foreach {i => println(t.charAt(i))}
  8. print: (t: IChar)Unit
  9. scala> print("gurk")
  10. g
  11. u
  12. r
  13. k

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))