|
View:
New views
11 Messages
—
Rating Filter:
Alert me
|
|
|
How to use Ordered with traits and primitive number types?Im stuck on seemingly simple question of how to use Ordered[T] with
traits and primitive number types like Int, Float etc? Neither this: trait A[T <: Ordered[T]] class B extends A[Float] ..nor this: trait A[T <% Ordered[T]] class B extends A[Float] ..nor this: trait A[Ordered[T]] class B extends A[Ordered[Float]] ..compile. How can I express that trait A takes a type parameter T that must be Ordered or orderable? BTW is there a fairly comprehensive article/guide to using Ordered anywhere, beyond the coverage in Stairway book? -Ben |
|
|
Re: How to use Ordered with traits and primitive number types?try this:
abstract class A[T <% Ordered[T]] class B extends A[Int] You need the implicit type bound to automagically convert Int to Ordered (via RichInt) But you can't have implicit type parameters on traits. That's why trait[T <% Ordered[T]] fails to compile. -Robbert. On Mon, Nov 9, 2009 at 7:35 AM, Ben Hutchison <brhutchison@...> wrote: > Im stuck on seemingly simple question of how to use Ordered[T] with > traits and primitive number types like Int, Float etc? > > Neither this: > > trait A[T <: Ordered[T]] > class B extends A[Float] > > ..nor this: > > trait A[T <% Ordered[T]] > class B extends A[Float] > > ..nor this: > > trait A[Ordered[T]] > class B extends A[Ordered[Float]] > > ..compile. > > How can I express that trait A takes a type parameter T that must be > Ordered or orderable? > > BTW is there a fairly comprehensive article/guide to using Ordered > anywhere, beyond the coverage in Stairway book? > > -Ben > |
|
|
Re: How to use Ordered with traits and primitive number types?On Mon, Nov 9, 2009 at 8:34 PM, Robbert van Dalen
<robbert.van.dalen@...> wrote: > abstract class A[T <% Ordered[T]] > class B extends A[Int] Thanks for your input. I may come across as slightly grumpy saying this, but an abstract class is (to me) no substitute for a trait. The single inheritance rule around classes is a ticking anti-symmetric, non-composeable time bomb. Its fine when you have a localised, single-purpose hierarchy like some alternate cases. But for general reuse, a software component must be willing to co-exist peaceably with peers without making claims of exclusivity. I got teeth-clenchingly sick of it in Java and Im not going back there! Is there not another better solution? -Ben > > You need the implicit type bound to automagically convert Int to > Ordered (via RichInt) > But you can't have implicit type parameters on traits. That's why > trait[T <% Ordered[T]] fails to compile. > > -Robbert. > > On Mon, Nov 9, 2009 at 7:35 AM, Ben Hutchison <brhutchison@...> wrote: >> Im stuck on seemingly simple question of how to use Ordered[T] with >> traits and primitive number types like Int, Float etc? >> >> Neither this: >> >> trait A[T <: Ordered[T]] >> class B extends A[Float] >> >> ..nor this: >> >> trait A[T <% Ordered[T]] >> class B extends A[Float] >> >> ..nor this: >> >> trait A[Ordered[T]] >> class B extends A[Ordered[Float]] >> >> ..compile. >> >> How can I express that trait A takes a type parameter T that must be >> Ordered or orderable? >> >> BTW is there a fairly comprehensive article/guide to using Ordered >> anywhere, beyond the coverage in Stairway book? >> >> -Ben >> > |
|
|
Re: How to use Ordered with traits and primitive number types?> Is there not another better solution?
Yes. Zero inheritance. :) -- Ricky Clarkson Java and Scala Programmer, AD Holdings +44 1565 770804 Skype: ricky_clarkson Google Talk: ricky.clarkson@... Google Wave: ricky.clarkson@... |
|
|
Re: How to use Ordered with traits and primitive number types?On Mon, Nov 9, 2009 at 9:40 PM, Ricky Clarkson <ricky.clarkson@...> wrote:
>> Is there not another better solution? > > Yes. Zero inheritance. :) I don't really buy that line of reasoning... In Java-land, I experienced the movement from "Inheritance" to "Composition". It was an improvement, but in practice, it meant lots of fields and lots of boilerplate delegation. Its precisely that delegation that traits enable you to remove. You can collapse down what we would be a graph of objects in Java, into a single multi-faceted object in Scala. And remove alot of boilerplate in the process. -Ben > > -- > Ricky Clarkson > Java and Scala Programmer, AD Holdings > +44 1565 770804 > Skype: ricky_clarkson > Google Talk: ricky.clarkson@... > Google Wave: ricky.clarkson@... > |
|
|
Re: How to use Ordered with traits and primitive number types?>> Yes. Zero inheritance. :)
> > I don't really buy that line of reasoning... > > In Java-land, I experienced the movement from "Inheritance" to > "Composition". It was an improvement, but in practice, it meant lots > of fields and lots of boilerplate delegation. I don't buy that line of reasoning. What forces you to have lots of fields is having lots of composition. What forces you to have lots of boilerplate delegation is trying to hide the lots of composition that you have the fields for. -- Ricky Clarkson Java and Scala Programmer, AD Holdings +44 1565 770804 Skype: ricky_clarkson Google Talk: ricky.clarkson@... Google Wave: ricky.clarkson@... |
|
|
Re: How to use Ordered with traits and primitive number types?When you were learning, you were likely taught that inheritance looks
like a Car and a Vehicle with an upward arrow pointing from Car to Vehicle. I hope to relieve you of these training wheels. What does that upward pointing arrow really mean? Actually it means that there if there exists an element in the set Car then you also implicitly have an element in the set Vehicle. Or, if we were to make good use of the Curry-Howard isomorphism, a Car implies a Vehicle. So if a Car implies a Vehicle, why is the arrow pointing upward? Because it's pointing the wrong way! It should be pointing right-ward, like this: Car => Vehicle. What we have now is a function. However, we don't have an equivalent relationship, since the right-ward pointing arrow requires the user to be *explicit*. That is to say, to get from Car to Vehicle, you have to explicitly say "do the thing that gets me from Car to Vehicle." You might call it "def carVehicler" or something. So how do we alleviate this? Well, languages like Scala and Haskell have implicit dictionary passing. We can have all the goodness of inheritance without all the nasties, which I will omit for now. In Scala, this is done with the implicit keyword (in Haskell, with the class/instance keywords). Does the aforementioned example generalise? Yes it does and this is perhaps the most important point. Don't let the Car => Vehicle function grab all your attention, *every* function has this property. Do you have a Int => Person function? Why doesn't Int inherit from Person then? It's arbitrary and is better explained by a psychologist. Ignoring limitations of Scala itself (syntax, limitations of implicit), inheritance is always a loss. I hope you feel better soon. Ben Hutchison wrote: > On Mon, Nov 9, 2009 at 8:34 PM, Robbert van Dalen > <robbert.van.dalen@...> wrote: > >> abstract class A[T <% Ordered[T]] >> class B extends A[Int] >> > > Thanks for your input. I may come across as slightly grumpy saying > this, but an abstract class is (to me) no substitute for a trait. > > The single inheritance rule around classes is a ticking > anti-symmetric, non-composeable time bomb. Its fine when you have a > localised, single-purpose hierarchy like some alternate cases. But for > general reuse, a software component must be willing to co-exist > peaceably with peers without making claims of exclusivity. I got > teeth-clenchingly sick of it in Java and Im not going back there! > > Is there not another better solution? > > -Ben > > >> You need the implicit type bound to automagically convert Int to >> Ordered (via RichInt) >> But you can't have implicit type parameters on traits. That's why >> trait[T <% Ordered[T]] fails to compile. >> >> -Robbert. >> >> On Mon, Nov 9, 2009 at 7:35 AM, Ben Hutchison <brhutchison@...> wrote: >> >>> Im stuck on seemingly simple question of how to use Ordered[T] with >>> traits and primitive number types like Int, Float etc? >>> >>> Neither this: >>> >>> trait A[T <: Ordered[T]] >>> class B extends A[Float] >>> >>> ..nor this: >>> >>> trait A[T <% Ordered[T]] >>> class B extends A[Float] >>> >>> ..nor this: >>> >>> trait A[Ordered[T]] >>> class B extends A[Ordered[Float]] >>> >>> ..compile. >>> >>> How can I express that trait A takes a type parameter T that must be >>> Ordered or orderable? >>> >>> BTW is there a fairly comprehensive article/guide to using Ordered >>> anywhere, beyond the coverage in Stairway book? >>> >>> -Ben >>> >>> > > -- Tony Morris http://tmorris.net/ |
|
|
Re: How to use Ordered with traits and primitive number types?On Mon, Nov 9, 2009 at 9:58 PM, Ricky Clarkson <ricky.clarkson@...> wrote:
>>> Yes. Zero inheritance. :) >> >> I don't really buy that line of reasoning... >> >> In Java-land, I experienced the movement from "Inheritance" to >> "Composition". It was an improvement, but in practice, it meant lots >> of fields and lots of boilerplate delegation. > > I don't buy that line of reasoning. What forces you to have lots of > fields is having lots of composition. What forces you to have lots of > boilerplate delegation is trying to hide the lots of composition that > you have the fields for. Maybe we're drifting towards an OO vs Functional rift in this conversation... If you want to do the /same thing/ to several different objects, you can either [OO-] imbue the various objects with the ability to do that thing , which is easiest to do via traits & mixin composition [Functional-] define functions independently of the target objects, and expose their data via some generic form. Lets get specific. The use-case the started this off was a desire to define a specialized form of ordering over homogeneous containers of ordered items (basically, vectors). I dont know the correct terminology, but in some fields it might be called "dominance": that every value in one container is greater than the matching item in the other, or the reverse. Here's my first attempt, from the OO-school (it uses a little custom richness): trait HasOrderedVectorComponents[T <: Ordered[T]] { def components:Seq[T] def all_>(other:HasOrderedVectorComponents[T]):Boolean = all(other, _ > _ ) def all_<(other:HasOrderedVectorComponents[T]):Boolean = all(other, _ < _ ) def all_<=(other:HasOrderedVectorComponents[T]):Boolean = all(other,_ <= _ ) def all_>=(other:HasOrderedVectorComponents[T]):Boolean = all(other,_ >= _ ) private def all(other:HasOrderedVectorComponents[T], predicate: (T,T)=>Boolean) = { components.zipWith(other.components)(predicate).&&? } } But I see now that I could equally go down the functional path and define 4 unbound functions: Seq[(T, T)] =>Boolean To me, that just doesnt seem as nice. Maybe Im simply OO brainwashed... -Ben > > -- > Ricky Clarkson > Java and Scala Programmer, AD Holdings > +44 1565 770804 > Skype: ricky_clarkson > Google Talk: ricky.clarkson@... > Google Wave: ricky.clarkson@... > |
|
|
Re: How to use Ordered with traits and primitive number types?On Mon, Nov 9, 2009 at 10:04 PM, Tony Morris <tonymorris@...> wrote:
> Well, languages like Scala and Haskell have > implicit dictionary passing. We can have all the goodness of inheritance > without all the nasties, which I will omit for now. In Scala, this is > done with the implicit keyword (in Haskell, with the class/instance > keywords). > Please elaborate. The Haskell-Typeclass ~ Scala-implicit connection is something Ive been curious for sometime about but not understood. I first encountered the idea here: http://lampwww.epfl.ch/~odersky/talks/wg2.8-boston06.pdf How do you use the word "dictionary" above. How is it different from the "vtable" of C++? Given that Haskell is early-bound, while Scala is late-bound, I would have guessed that their function resolution mechanisms have more differences than similarities, but you suggest otherwise? -Ben |
|
|
Re: How to use Ordered with traits and primitive number types?IIRC this paper mentions it in an understandable way -
http://www.comlab.ox.ac.uk/jeremy.gibbons/publications/scalagp.pdf Andrew 2009/11/9 Ben Hutchison <brhutchison@...>: > The Haskell-Typeclass ~ Scala-implicit connection is something Ive > been curious for sometime about but not understood. |
|
|
Re: How to use Ordered with traits and primitive number types?Hello Ben,
Here is an explanation I've used before successfully. I've not seen it documented elsewhere. Consider the type of the elem function: (Eq a) => a -> [a] -> Bool It is pretty clear what it does: Prelude> 7 `elem` [1,2,3] False Prelude> 2 `elem` [1,2,3] True If you were to read aloud the type of elem, you might say something like: "takes a value of some type (a), such that (a) is in the class of types for which equality (Eq) is defined, and a list of that same type (a) and returns true or false." Now suppose I wrote a new data type: newtype Eq' a = Eq' { equal :: a -> a -> Bool } I could now rewrite the elem function using this type instead: Eq' a -> a -> a -> Bool Notice now you don't treat Eq specially -- it's simply a data type. Specifically, you pass it *explicitly* just like the other arguments. This is more like a simple Java interface or a Scala trait. However, Scala has a trick up its sleeve; the implicit keyword. This allows us to "pass the Eq implicitly", which is precisely what the type-class is doing. On that note, I might point out that I have strong objections to the common suggestion that type-classes are like Java interfaces, since they most certainly are not. The implicit use is a crucially defining feature of type-classes, of which Java has no analogy. Data types are more like Java interfaces. Hope that helps. Ben Hutchison wrote: > On Mon, Nov 9, 2009 at 10:04 PM, Tony Morris <tonymorris@...> wrote: > >> Well, languages like Scala and Haskell have >> implicit dictionary passing. We can have all the goodness of inheritance >> without all the nasties, which I will omit for now. In Scala, this is >> done with the implicit keyword (in Haskell, with the class/instance >> keywords). >> >> > > Please elaborate. > > The Haskell-Typeclass ~ Scala-implicit connection is something Ive > been curious for sometime about but not understood. I first > encountered the idea here: > http://lampwww.epfl.ch/~odersky/talks/wg2.8-boston06.pdf > > How do you use the word "dictionary" above. How is it different from > the "vtable" of C++? > > Given that Haskell is early-bound, while Scala is late-bound, I would > have guessed that their function resolution mechanisms have more > differences than similarities, but you suggest otherwise? > > -Ben > > -- Tony Morris http://tmorris.net/ |
| Free embeddable forum powered by Nabble | Forum Help |