Re: Sealed trait hierarchies and downcasting
Sébastien Doeraene <[email protected]>
| Newsgroups | gmane.comp.lang.scala |
|---|---|
| Message-ID | <CAJwkOg72YY6kqwpeJW-0mghB_8AiHnVXKjOL6qmj0CV6OcGjVg@mail.gmail.com> |
Inheriting from a private class/trait in a public class/trait is a sin. It shouldn't even be allowed by scalac, IMO. Sébastien On Mon, Mar 2, 2015 at 5:46 PM, Daniel Armak <[email protected]> wrote: > How about: > > private trait Tree { def size: Int = ... } > sealed trait Foo extends Tree { def size: Int } > private object Tree { > > case class Leaf(...) extends Foo > } > > Then, implementation code can treat any Foo as a Tree, but to outsiders > Tree is not accessible. > > > Daniel Armak > > On Mon, Mar 2, 2015 at 5:32 PM, rklaehn <[email protected]> wrote: > >> Am Montag, 2. März 2015 13:29:21 UTC+1 schrieb Stephen Compall: >>> >>> On Mon, 2015-03-02 at 11:10 +0100, Rüdiger Klaehn wrote: >>> > sealed trait Foo >>> > >>> > object Foo { >>> > >>> > def empty: Foo = ... >>> > >>> > def apply(...): Foo = ... >>> > >>> > private sealed trait Tree extends Foo >>> > >>> > private case class Leaf(...) extends Tree >>> > >>> > private case class Branch(...) extends Tree >>> > } >>> > >>> > Basically have a sealed trait or sealed abstract class for the public >>> > interface, and then a completely >>> > private hierarchy that is the only implementation. This is a nice way >>> > to hide implementation details while still not having the overhead of >>> > boxing or the annoyance of wrapping in a value class. >>> > >>> > However, a problem with this approach is that the compiler does not >>> > seem to know that a Foo must always be a Tree. >>> >>> I don't see how you would lose any of the benefits you stated if `Tree` >>> simply wasn't included at all. You would remove no overhead and reveal >>> no implementation details by eliminating `Tree`. >>> >>> >> I want Foo to be a pure trait / interface, and not have any >> implementation there. Tree will contain implementation and private helper >> methods. E.g. >> >> sealed trait Foo { def size: Int } >> >> private sealed class Tree extends Foo { >> final def size:Int = this match { case Leaf(_) => 1; case Branch(l, r) >> => l.size + r.size } >> } >> >> I think this is preferable to code where the implementation has to be >> carefully hidden by hiding all helper methods. With the latter, it is very >> easy to accidentally introduce a public method. With a separate trait, this >> is almost impossible. >> >> -- >> You received this message because you are subscribed to the Google Groups >> "scala-language" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected]. >> For more options, visit https://groups.google.com/d/optout. >> > > -- > You received this message because you are subscribed to the Google Groups > "scala-language" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "scala-language" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.