I'm currently trying to wrap my mind around Scala with an intention to use it for my next project that has to deal with DICOM. DICOM has quite broad specification that spans over thousands of pages of the standard. My understanding of DICOM is quite limited, but in short DICOM objects - IODs (Information Object Definition) are composed of Modules, and Modules are a collection of typed name-value attribute pairs. It's further complicated by optionality of some modules and attributes. For example:
SimpleImageIOD: {
PatientModule: {
name: String
dateOfBirth: DateTime
}
StudyModule: {
name: String
date: DateTime (optional)
}
SeriesModule: {
name: String
}
ImageModule: {
height: Integer
width: Integer
pixelSize: Double (optional)
}
EquipmentModule: { (optional)
type: String
}
}
There are tons of modules, they might be composed in various combinations forming different IODs. Scala in turn has lots of modeling power with all the traits, case classes, dynamic classes, etc. How would you model such domain in Scala? I'm quite new to the language but I've been thinking to use immutable case classes to define modules, then aggregate them in various IODs, and use lenses for updating:
case class Patient(name: String, dateOfBirth: DateTime)
case class Study(name: String, date: Option[DateTime])
case class Series(name: String)
case class Image(height: Integer, width: Integer, pixelSize: Option[Double])
case class Equipment(type: String)
case class SimpleImageIOD(patient: Patient, study: Study, series: Series,
image: Image, equipment: Option[Equipment])
object Patient {
val nameL: Lens[Patient, String] = ...
val dateOfBirthL: Lens[Patient, DateTime] = ...
}
object SimpleImageIOD {
val patientL: Lens[SimpleImageIOD, Patient] = ...
val patientNamel = patientL andThen Patient.nameL
}
Etc etc. With respect to lenses it might become a problem to code all the boilerplate - there's going be order of M x N x L
lenses to cover whole domain for M
IODs, N
modules, and L
attributes. Also optionality of some fields complicates the task immensely at least with scalaz-seven
.
What other viable approaches are available there that align with the spirit of Scala?