I am using Rx for a scheduling project. One of the methods looks like:
let strike (scheduler: 'a when 'a :> IScheduler option) strikeTime source =
match strikeTime with
| StrikeOnceAt due -> strikeOnce scheduler (Choice1Of2 due) source
| StrikeOnceAfter delay -> strikeOnce scheduler (Choice2Of2 delay) source
| StrikeEvery (period, last) -> strikeEvery scheduler period last source
When testing, I am using a HistoricalScheduler
, which, of course, derives from IScheduler
.
let ``Repeater strikes at given rate per minute`` rpm =
let sched = new HistoricalScheduler(DateTimeOffset.Now)
let rate = rpm |> int64 |> Min |> toRate
let repeat = Repeater.StrikeEvery (rate, None)
use actual = Repeater.strike (Some sched) repeat source
Instead of casting sched :> IScheduler
in the calling code, I'm hoping to use type constraints like shown above.
I am unsure whether to represent the constraint as...
(scheduler: 'a option when 'a :> IScheduler)
-or-
(scheduler: 'a when 'a :> IScheduler option)
Is this just preference? Is there a reason to choose one way over the other?
When deciding between
(scheduler: 'a option when 'a :> IScheduler)
-or-
(scheduler: 'a when 'a :> IScheduler option)
,
the compiler will tell you that the first variant resolves as
(scheduler: #IScheduler option)
while the second should generate a warning that it has been constrained to
(scheduler: IScheduler option)
.
Therefore your first variant does actually what you want it to do. The #
notation is called flexible type.