记录F#中的方法

Pan*_*nos 5 f# records

我为我的场景写了一个简单的例子.我创建了一个记录类型Switch

type State =
    | On
    | Off
    with
        member this.flip =
            match this with
            | On -> Off
            | Off -> On

type Switch = { State : State }
Run Code Online (Sandbox Code Playgroud)

然后我写了一个函数,它创建了一个元素更改的记录副本

let flip switch = { switch with State = switch.State.flip } 
Run Code Online (Sandbox Code Playgroud)

flip很多次连续写我

let flipMany times switch =
    [1 .. times]
    |> List.fold (fun (sw : Switch) _ -> flip sw) switch
Run Code Online (Sandbox Code Playgroud)

如果我想把这两个函数作为方法放在记录上,我会写

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
Run Code Online (Sandbox Code Playgroud)

这样做有什么不对吗?它同样有效吗?sw.flip每次在不同的对象上调用该函数感觉有点不舒服.

编辑:这只是一个简单的例子,以解释我的问题.我的问题是函数如何flipManyflipMany记录中的方法进行比较.实施可能是天真的,但在两种情况下都是相同的.

Gen*_*ski 12

你的意图可以像简单的那样实现

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
Run Code Online (Sandbox Code Playgroud)

在比较静态函数和对象方法的更广泛的上下文中,惯用的方法是坚持功能选项.函数具有显式参数,并且不能依赖于任何边状态,而是依赖于参数状态,以产生幂等结果值.相反,对象方法隐式地将类的实例作为参数获取,并且可以不仅从参数派生结果值,而且还基于其他类字段的状态,这与纯函数的幂等性属性不一致. .

为了更好地感受这种差异,可能有助于通过F#组件设计指南阅读并探索F#核心库设计.