- scala> trait S {
- | type x
- | def get : x
- | }
- defined trait S
- scala> var sample = new S{
- | type x = Int
- | def get = 3
- | }
- sample: java.lang.Object with S{type x = Int} = $anon$1@397af435
- scala> sample = new S {
- | type x = Double
- | def get = 3.0
- | }
- < console>:7: error: type mismatch;
- found : java.lang.Object with S
- required: java.lang.Object with S{type x = Int}
- sample = new S {
In this example sample uses type inference so the actual type is S with underlying type Int. The consequence is that sample can only be assigned with instances of S with type x = Int. The fix is to explicitly declare the variable type:
- scala> var sample2 : S = new S{
- | type x = Int
- | def get = 3
- | }
- sample2: S = $anon$1@31602bbc
- scala> sample2 = new S {
- | type x = Double
- | def get = 3.0
- | }
- sample2: S = $anon$1@4de5ed7b
The same thing happens when declaring functions and allows type inference for function definition
- scala> class Fac {
- | def newS = new S {
- | type x = Int
- | def get = 3
- | }
- | }
- defined class Fac
- scala> class SubFac extends Fac{
- | override def newS = new S {
- | type x = Double
- | def get = 3.0
- | }
- | }
- < console>:8: error: type mismatch;
- found : java.lang.Object with S
- required: java.lang.Object with S{type x = Int}
- override def newS = new S {
The fix for this example is to be explicit in the definition of the function in the superclass
The more I experiment with abstract types, the more I feel clueless. The rules for how they are used are tough but figuring out how they *should* be used has been truly humbling. Its easy to get along without them but I feel like I'm standing alone in the corner at the party. Everybody else gets to have fun :-)
ReplyDeleteAside from the cake pattern, all advanced uses of abstract types appear to be in large projects like Lift, making learning the 'patterns' pretty tough. These posts are a help. Thanks for doing this.
Glad I can do a little to help.
ReplyDelete