1
votes

I was doing some experiments with existential types. First I defined a small class hierarchy:

trait Fruit
case class Apple extends Fruit
case class Banana extends Fruit

Then I wanted a set to which I could add different types of Fruit:

val set1: Set[_ >: Fruit] = Set()
// Which is equivalent to:
val set2: Set[F] forSome { type F >: Fruit } = Set()

// This compiles
set1 += Apple()
set1 += Banana()
set2 += Apple()
set2 += Banana()

So far, so good. But now I want a set of functions from some Fruit to Unit:

// This still compiles
val set3: Set[(_ <: Fruit) => Unit] = Set()
// But this doesn't
val set4: Set[F => Unit] forSome { type F <: Fruit } = Set()

That last line gives me the following errors:

  • no type parameters for method apply: (elems: A*)scala.collection.mutable.Set[A] in class GenericCompanion exist so that it can be applied to arguments () --- because --- undetermined type
  • type mismatch; found : scala.collection.mutable.Set[A] required: scala.collection.mutable.Set[F => Unit] forSome { type F <: Fruit }

Why do I get those errors, when supposedly my set4 is equivalent to set3? Did I made a mistake somewhere?

If I say Set[(F forSome { F <: Fruit }) => Unit] then that lines compiles, but I can't add functions to that set:

  • type mismatch; found : Apple => Unit required: F forSome { type F <: Fruit } => Unit

Where I can add the same function to set3 with no problem.

Another problem I had is that I can't put the existential types on the right side of the assignment:

// Does not compile, I get "unbound wildcard type"
val set1 = Set[_ >: Fruit]()

Why is that?

1

1 Answers

1
votes

Some mistake in code:

val set4: Set[F => Unit] forSome { type F <: Fruit } = Set()

It need to be defined as:

val set4: Set[(F => Unit) forSome { type F <: Fruit }] = Set()
//OR:    
val set4: Set[Function1[F,Unit] forSome { type F <: Fruit }] = Set() 

Because in your definition forSome is related to Set but need to be related to Function1

Update:

Why does not compile:

val set1 = Set[_ >: Fruit]()

The reason is simple. From left side of = is defining the type and variable name, from right side is calling type constructor and class constructor. And you try to call type constructor with undefined value but in need to construct final type and it is a reason of error.