I have this F# class
module File1
open System
open System.Collections.Generic
type TimeRangeList<'e>(getter: DateTime * DateTime -> List<'e>, ?maybe_tFrom: DateTime, ?maybe_tTo: DateTime) as this =
inherit List<'e>()
//inherit List<'e>(getter(defaultArg maybe_tTo DateTime.Now, defaultArg maybe_tFrom ((defaultArg maybe_tTo DateTime.Now).AddDays(-1.0))))
let tTo = defaultArg maybe_tTo DateTime.Now
let tFrom = defaultArg maybe_tFrom (tTo.AddDays(-1.0))
do this.AddRange(getter(tFrom, tTo))
now I want to add constructors and use the syntax as in here
type TimeRangeList<'e> =
inherit List<'e>
val tFrom: DateTime
val tTo: DateTime
new (getter: DateTime * DateTime -> List<'e>, ?maybe_tFrom: DateTime, ?maybe_tTo: DateTime) = {
inherit List<'e>()
//inherit List<'e>(defaultArg maybe_tFrom ((defaultArg maybe_tTo DateTime.Now).AddDays(-1.0)), getter(defaultArg maybe_tTo DateTime.Now))
tTo = defaultArg maybe_tTo DateTime.Now
tFrom = defaultArg maybe_tFrom (tTo.AddDays(-1.0)) //tTo undefined
//tFrom = defaultArg maybe_tFrom ((defaultArg maybe_tTo DateTime.Now).AddDays(-1.0))
}
do this.AddRange(getter(tFrom, tTo)) //primary constructor required
this code gives two errors:
This is the syntax you're looking for:
module File1
open System
open System.Collections.Generic
type TimeRangeList<'e> =
inherit List<'e>
val tFrom: DateTime
val tTo: DateTime
new (getter: DateTime * DateTime -> List<'e>, ?maybe_tFrom: DateTime, ?maybe_tTo: DateTime) as this =
let to_ = defaultArg maybe_tTo DateTime.Now
let from_ = defaultArg maybe_tFrom (to_.AddDays(-1.0))
{
inherit List<'e>()
tTo = to_
tFrom = from_
}
then
this.AddRange(getter(this.tFrom, this.tTo))
Documentation links:
then keyword instead of doas this after the new() expressionTo explain a little bit, the { field = value; field2 = value2 } syntax doesn't have to be the only expression found in the new() block that defines a secondary constructor. It just has to be the last expression, that is, the expression that is returned. (Here, even though technically the then block is the "last" block in the constructor, its return value (which is required to be unit) is ignored and the actual return value of the constructor is the last expression not found in a then block). Therefore, it's safe to use let expressions earlier to define the values you want to put into your class's fields, and those let expressions can reference each other just as they would in normal code. So if you have a complicated or expensive calculation that you need to put into several fields, you could so something like:
new () =
let result = expensiveCalculationIWantToDoOnlyOnce()
{ field1 = result; field2 = result + 1; field3 = result + 2 }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With