I have written a simple example for my scenario. I create a record type Switch
type State =
| On
| Off
with
member this.flip =
match this with
| On -> Off
| Off -> On
type Switch = { State : State }
and then I write a function that creates a copy of the record with one element changed
let flip switch = { switch with State = switch.State.flip }
To flip
many successive times I write
let flipMany times switch =
[1 .. times]
|> List.fold (fun (sw : Switch) _ -> flip sw) switch
If I want put these two functions on the record as methods, I write instead
type Switch =
{ State : State }
member this.flip =
{ this with State = this.State.flip }
member this.flipMany times =
[1 .. times]
|> List.fold (fun (sw : Switch) _ -> sw.flip) this
Is there anything wrong with doing this? Is it equally efficient? It feels a bit uncomfortable calling the function sw.flip
on a different object every single time.
Edit: this is just a simple example in order to explain my question. My question is on how the function flipMany
compares with the flipMany
method on the record. The implementation might be naive, but it is the same in both of cases.
Your intent can be implemented as simple as
let flipMany times switch =
match (times % 2) with
| 1 -> { switch with State = switch.State.flip }
| _ -> switch
type Switch =
{ State : State }
member this.Flip = { this with State = this.State.flip }
member this.FlipMany times =
match (times % 2) with | 1 -> this.Flip | _ -> this
In the broader context of comparing a static function versus an object's method the idiomatic way would be sticking to function option. A function has explicit arguments and must not depend on any side state, but state of arguments, to produce an idempotent result value. On the contrary, an object method implicitly gets an instance of the class as an argument and may derive result value not just from arguments, but based on the state of other class fields too, which is not in line with idempotency property of a pure function.
To feel this difference better it may help reading thru F# Components Design Guidelines and exploring F# Core libraries design.
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