type A (a,b) as this =
let c = "sum"
do printfn "The sum is " (a+b)
Easy! But class A only has one constructor. Suppose we want another? The obvious guess would be
type B (a,b) as this =
let c = "sum"
do printfn "The sum is " (a+b)
new (d) = B(a,0)
but this doesn't work for a number of reasons. You can't have
let
or do
sections in your type if you have multiple constructors. So this means that a
, b
and c
have to be defined in the new
function. This means, of course, that you need to use explicit class syntax. The action can then follow the initialisation in a then
clause.
type C =
val a :float
val b :int
val c :string
new (_a,_b) = { a=_a; b=_b; c="sum"} then printfn "The sum is " (a+(float b))
new (_a) = { a=_a; b=0; (* Yes, you have to initialise all the class members *) c="sum"} then printfn "The sum is " (a+(float b))
Whew! Complicated! And repetitive, potentially! It is possible to call functions in the
then
clause but you still have to initialise all the members in the record clause.It's more fiddly in the presence of inheritance unfortunately. In this case the record initialiser has to include inherit Cbase(a).
Here's one I've used in production code, anonymised...
type drv = class
inherit bse
val _parser : Parser
val _columnExtractors : List
new (configuration:ExpConfig ) as x =
{inherit bse(configuration); _parser = new Parser(configuration); _columnExtractors = new List()}
then x.Init()
new (configuration:ExpConfig, parser:Parser) as this =
{inherit bse(configuration); _parser = parser; _columnExtractors = new List()}
then this.Init()
member private x.Init() =
printfn "blah blah blah"
end
No comments:
Post a Comment