6

私は自分のシナリオの簡単な例を書きました。レコードタイプを作成しますSwitch

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

type Switch = { State : State }

次に、1つの要素が変更されたレコードのコピーを作成する関数を作成します

let flip switch = { switch with State = switch.State.flip } 

flip度も書いています

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

これらの2つの関数をメソッドとしてレコードに入れたい場合は、代わりに書き込みます

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

これを行うことに何か問題がありますか?それは同じくらい効率的ですか?sw.flip毎回異なるオブジェクトで関数を呼び出すのは少し不快に感じます。

編集:これは私の質問を説明するための簡単な例です。私の質問は、関数がレコードflipManyのメソッドとどのように比較されるかについてです。flipMany実装は単純かもしれませんが、どちらの場合も同じです。

4

1 に答える 1

14

あなたの意図は、次のように簡単に実装できます。

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

静的関数とオブジェクトのメソッドを比較するというより広い文脈では、慣用的な方法は関数オプションに固執するでしょう。関数には明示的な引数があり、べき等の結果値を生成するために、サイドの状態ではなく、引数の状態に依存する必要があります。それどころか、オブジェクトメソッドは暗黙的にクラスのインスタンスを引数として取得し、引数からだけでなく、純粋関数のべき等プロパティと一致しない他のクラスフィールドの状態にも基づいて結果値を導出する場合があります。 。

この違いをよりよく感じるには、F#コンポーネントの設計ガイドラインを読み、 F#コアライブラリの設計を調べると役立つ場合があります。

于 2012-06-23T20:51:13.393 に答える