artemka
artemka

Reputation: 444

Scala's generics

I want to write a function for process sequence, like this:

def wrap[A >: Seq[_], B](seq : A)(f : () => B): Option[B] = {
    if(seq.isEmpty) None
    else Some(f())
}

But it doesn't work error:

error: value isEmpty is not a member of type parameter A

if(seq.isEmpty) None

What did I do wrong?

Upvotes: 1

Views: 3818

Answers (2)

Didier Dupont
Didier Dupont

Reputation: 29548

What you did wrong is >:, you need <:

A <: B means the type A is less than the type B, in that if you think of the type as the set of all values belonging to it, type A is included in type B. This is java A extends B. >: is java A super B.

It is of course natural to think that A is greater than B, in that instances of A offer at least as many services/guarantees as instances of B do. But the usual notation (not only in scala) of subtyping is for inclusion.

That being said, @dhg answer is correct in that you do not need the generic parameter for this particular problem.

Upvotes: 4

dhg
dhg

Reputation: 52701

You don't need to say anything about A at all. Just say that the first argument to wrap is a Seq, then you can pass in a Seq or any subclass thereof:

def wrap[B](seq : Seq[_])(f : () => B): Option[B] = {
    if(seq.isEmpty) None
    else Some(f())
}

wrap(List(1,2,3))(() => "hi") //returns Some("hi")

Upvotes: 6

Related Questions