1

Is it possible to have mutual recursive types in scala?

I have a xml files with a list of bugtracker issues. It's raw data. The model has different issue-types like "tasks", "subtasks", "bug", "special-bug".

Now I want to parse my raw-data to a hierarchical structure of tasks and subtasks:

// data type for field contents
abstract class Field
case class Id(raw : string) extends Field
case class Status(raw : string) extends Field
...

// data type for primary model
abstract class Issue(id : String, ...)
case class Task(id : Id, status : Status ..., subtasks : List[Subtask] ) extends Issue(id, ...)
case class Subtask(id : Id, status : Status ..., parent: Task) extends Issue(id, ...)

I wonder if this mutual recursion is theoretically possible?

Second question:

I render the model to some wiki-markup. This works fine with an overloaded recursive render() : String in the class for the datatype. (Probably I should have a "Renderable" Superclass !?)

What would be the cleanest way for parsing, i.e. I'd like to have a recursive

fromXML : scala.xml.Elem => Issue / Field

Where would I put it? How would it look like? IIUC, the companion is autogenerated for case-classes so I cant add to it?

I have this e.g.:

def fromXml(e : Elem) = e match {
  case <a>test</a> => Id("test") 
  case _ => Status("Pre-analysed")
}

But I failed to give the function a type. What is the type of that function ?

I also thought about passing the xml-elem directly to the constructor of the ADT, would that be clever? Or should I separate XML-parsing and model-creation ?


Jesus, after learning the scala basics and doing some scripts and functions (and thinking too much java), I finally understood how to write ADTs and can express myself nearly as in good old Haskell times :-)

Bastl
  • 2,926
  • 5
  • 27
  • 48
  • 1
    You should improve the structure of your question to make it clearer what your overall goals are; try to group your subquestions in a meaningful way (I did not downvote you). – Malte Schwerhoff Aug 06 '12 at 20:22
  • @mhs: yes, you are right, I jsut wrote down the open ends of my project. Nevermind, your answer helps to get further ... – Bastl Aug 07 '12 at 06:35

1 Answers1

4

A: Regarding the initialisation of immutable, mutually dependent classes, have a look at this question.

B: Regarding your question render: Foo => String function vs. Renderable superclass, this is IMHO more or less a design decision between a functional and an object-oriented approach. I personally don't think that one of them is superior to the other, it is just a matter of taste. The paper "Independently Extensible Solutions to the Expression Problem" has a nice comparison between the two, although in a slightly more elaborate context (it is a great read, however).

C: Companion objects are created by the compiler, but if you also specify a companion object, the compiler will merge the two.

D: In your current class hierarchy there is no non-trivial common supertype for Issue and Field, which makes it difficult to give a meaningful return type for fromXML. You could work with an Either[Issue, Field], though, but this looks fishy to me. In general, I would avoid mixing functions that are supposed to return full-fledged nodes (e.g., Task) with those that return "internal" nodes (e.g., Status).

E: Did you had a look at existing solutions, e.g. scalaxb? You can find more links here and here.

Community
  • 1
  • 1
Malte Schwerhoff
  • 12,684
  • 4
  • 41
  • 71
  • concerning D: I see, but I already had problems with only the Field type. when I write fromXML(e : Elem) : Field, the match gives me incompatible types Field <-> Id, which I dont udnerstand since Id is a subclass of Field (in the OO sense). What's the (return) type of that function ? – Bastl Aug 07 '12 at 06:49