Donna Malayeri | 2 Jan 2010 18:18
Picon
Gravatar

Re: Structured types - restrictions?

I'm not sure how you could define the structural type so that it didn't refer to the type parameter. I think you're better off passing in the comparison function:

> def listMax[U, T <: List[U]] (l: T, max: (U, U) => U) = l.reduceLeft(max)

> listMax(List(1, 2, 3, 4), (_:Int) max (_:Int))
res16: Int = 4

Btw, the reason that Int doesn't conform to the type { def max[T](T) : T } is that the max function in Int is not parameterized.

Donna

On Mon, Dec 21, 2009 at 7:24 PM, Yoel Jacobsen <yoel.jacobsen <at> gmail.com> wrote:
Hello list,

I'm trying to understand what can and cannot be done with structured
types but can't find a complete documentation (sadly Programmingin
Scala does not contains a discussion of the subject).

To understand it I'm toying with a function that should find a
sequence's maximum.

Conceptually, to make the function really generic it should accept a
data structure of the form S[E] (Such as List[Int]) such that S
implements reduceLeft() and E implements max().

As I can't think of a way to describe S[E] in Scala I'll reduce the
problem to List[T] where T implements max().

My first failure at defining listMax using structural types is:

scala> def listMax[T](l:List[{def max(that:T):T}]) = l.reduceLeft(_ max _)
<console>:4: error: Parameter type in structural refinement may not refer to
abstract type defined outside that same refinement
      def listMax[T](l:List[{def max(that:T):T}]) = l.reduceLeft(_ max _)
                                          ^
<console>:4: error: type mismatch;
 found   : AnyRef{def max(T): T}
 required: T
      def listMax[T](l:List[{def max(that:T):T}]) = l.reduceLeft(_ max _)
                                                                       ^
If due to the first error I'm trying to specializing the max function
the compiler does not contains, but does not match l with List[Int]:

scala> def listMax(l:List[{def max[T](that:T):T}]) = l.reduceLeft(_ max _)
listMax: (List[AnyRef{def max[T](T): T}])AnyRef{def max[T](T): T}

scala> listMax(List(1,2,3,2,1))
<console>:6: error: type mismatch;
 found   : Int(1)
 required: AnyRef{def max[T](T): T}
      listMax(List(1,2,3,2,1))
                   ^

Therefore, I have two questions:

1. Is there a way to define in Scala the listMax function as
l.reduceLeft(_ max _) ?

2. Is there a way to define a seqMax function on all sequences (with
reduceLeft) on elements (with max) ?

Thanks,
 Yoel


Gmane