Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Record methods in F#

Tags:

f#

records

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.

like image 772
Panos Avatar asked Jun 23 '12 19:06

Panos


1 Answers

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.

like image 51
Gene Belitski Avatar answered Sep 20 '22 02:09

Gene Belitski