0

Traditional approach to algebraic types recommends something like it:

sealed trait CompositeType
final case class LeftBranch(left : String) extends CompositeType
final case class RightBranch(right : Int) extends CompoisteType
object Trivial extends CompositeType

The problem is that I can't extend CompositeType further to have more option (just like Double extends Float offering more accuracy and providing system for backward converting from Double to Float).

Scala gives you free to define own apply and unapply methods for building and matching instances of algebraic type.

Is there any project that tries to build framework for such types?

That may be usefull for actors metaphor. Currently actors receives untyped messages (as Any implies no type restrictions) matching known types and giving safe default for others. It breaks all type strict design of scala and restricting actors with more proper types would be really nice.


update:

Example clarifing my intentions:

sealed trait CompositeType1
final case class OtherBranch(x : Int, y : Int) extends CompositeType1
object Simple extends CompositeType1

trait ComplexChoice extends CompositionType with CompositionType1

I want to create CompositionType not as a root in type hierarchy but as one solid class. That may be extended further, mixing with other classes.

Let see some normal OOP usage:

trait ContractOne
trait ContractTwo

def method(arg : ContractOne with ContractTwo)

In this example function method need an argument that fit both contracts. What does mean contract for an algebraic type? Set of available constructors and matchers. What is natural view of extending an algebraic type? Extending set of constructors with some new values (just as Double extends Float with more precise floating point numbers)

CompositeType misses this conceptions evidiently. If I mix this two algebraic types I got set intersection instead of union. This is direct effect of chosen way for representing algebraic types as set of hierarchic subtypes. It gives more freedom to span choices outside initial types, but it lacks OOP features since inheritance is taken for element construction and may not be used for extending algebraic types itself.

Haskell has only one way for adding new choices to an algebraic type:

data CompositeType = LeftBranch String | RightBranch Int | Trivial
data CompositeType1 = OtherBranch Int Int | Simple
data ComplexChoice = CompositeType | CompositeType1

ComplexChoice is defined seamlessly in concept of haskell's data types. But handling it becomes complex, since I need reroute all methods as for composition. That's why composition is a solution in scala but troublesome and boilerplate one (if there is no compiler plugin that can generate code for composition pattern)

What I really need, is something like it:

ComplexChois condense CompositeType and CompositeType1

But object hierarchies may spawn only in one direction.

So there is need in some other way for defining algebraic types. There is space for it since infinite expanding of original trait is not something that really needed and most such traits is used with sealed keyword. Therefore some other less powerfull mechanism than extending may be used to represent data types.

ayvango
  • 5,627
  • 3
  • 28
  • 70

1 Answers1

1

As you note, objects are the end of the line for derivation of subtypes. You could, in this case, create another level of intermediate abstract type from which to derive sub-types (singleton or otherwise) of Trivial:

sealed trait Trivial extends CompositeType
object Trivia extends Trivial { ... }
class Triviality extends Trivia(...) { ... } \
...
Randall Schulz
  • 25,823
  • 4
  • 58
  • 81
  • You may furter branch CompositeType of course. But all this would still be CompositeType. I can not mixin some other trait into CompositeType. Something like `trait SuperComposite extends CompositeType with OtherComposite` and `SuperComposite` got both `CompositeType` and `OtherComposite` heirs as its *own* heirs – ayvango Mar 04 '13 at 18:33