Reputation: 2928
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:
Upvotes: 3
Views: 340
Reputation: 36718
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 do
as 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 }
Upvotes: 6
Reputation:
To fix the first problem you should give a name to the current object: new (...) as this =
and then access your variable with it this.tTo.AddDays(-1.0)
.
I don't have a solution yet for the second issue.
Upvotes: 1