Albert Romkes
Albert Romkes

Reputation: 1125

F# domain modelling with shared properties

I can't figure out how to do the following in idiomatic F# (slightly adjusted for clarity):

type Shared(name, label, multivalue) = 
  member val Name = name with get, set
  member val Label = label with get, set
  member val Multivalue = multivalue with get, set

type TextField(name, label, multivalue) = 
  inherit Shared(name, label, multivalue)
  member val Xslt = "" with get, set

type NumberField(name, label, multivalue) = 
  inherit Shared(name, label, multivalue)        

// helper 'create' function  
let textfield name label =
  TextField (name, label, false)

// helper 'create'  function
let numberfield name label = 
  NumberField (name, label, false)

let makemultivaluefield (field: Shared)  = 
  field.Multivalue <- true
  //field <- I would want this to return the parent type. E.g. TextField or NumberField    

// Actual code for creating / using above domain (DSL like syntax... that's the goal of this whole exercise)
let myTextField = 
  textfield "field" "field"
  |> makemultivaluefield

let myNumberField = 
  numberfield "fieldnumber" "field number label"
  |> makemultivaluefield

The |> makemultivaluefield call returns a unit now, but I want it to return a TextField or a NumberField (There are more classes like NumberField and TextField all with the same 3 properties declared in Shared).

Upvotes: 0

Views: 93

Answers (1)

scrwtp
scrwtp

Reputation: 13577

The approach with a minimal amount of change compared to your example would be something like this

let makemultivaluefield<'subtype when 'subtype :> Shared> (field: 'subtype) : 'subtype = 
  field.Multivalue <- true
  field

Make the function generic and then restrict it to subtypes of your Shared type. This should work fine for you unless your real life code is way more complex than the example.

Upvotes: 1

Related Questions