Menu principale

scale in alluminio professionali

Type Inference with Abstract Types

A second "gotcha" that one might get tripped up when dealing with abstract types is the signature of the concrete class contains type information about the abstract type. So if you are not explicit when assigning a variable or defining a function you can get unexpected compiler errors.

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{

| overridedef 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}

overridedef newS = new S {

The fix for this example is to be explicit in the definition of the function in the superclass