2

後で計算式の正規メソッドの 1 つで使用できる計算式でメソッドまたはスタンドアロン関数を作成することは可能ですか?

私はこのようなものが欲しい:

type FormletBuilder(ctx : HttpContext) =

    let get_int = 
        match Int32.TryParse (ctx.Request.["foo"]) with
        | (true, n) -> Some n
        | _ -> None

    //similar definitions for get_date, get_non_empty_str, etc...

    member x.Bind (read : 'a option, f : 'a -> option 'a) =
        match read with
        | Some x -> f(x)
        | None -> None      

    member x.Return (obj) = Some obj
    member x.Zero () = None



    let person = formlet ctx {

        let! id = get_int "id"
        let! name = get_non_empty_str "fullname"

        return Person(id, name)
    }

get_intしかし、コンパイラはそれが定義されていないと不平を言います。

4

2 に答える 2

2

letクラス定義のバインディングは常にプライベートです。代わりにa を定義できますmember

簡単な解決策として、次のことができます。

let formlet = FormletBuilder(ctx)
let person = formlet {
    let! id = formlet.get_int "id"
    ...
}
于 2014-11-12T18:03:04.703 に答える
1

あなたが実際に望んでいるのはおそらくモナドであり、ワークフローの引数は構文糖衣を利用するためだけにあることを理解しましたか? もしそうなら、あなたがすることを検討できる他のいくつかのことがあります:

  1. ずっと Haskell を使い、MaybeReader モナドを実装して、多分とリーダーの両方の部分が明示的な型になるようにします。
  2. 砂糖を片付けてください-コアビルダーメンバーのコンテキストが実際には必要ないことを理解していますか? もしそうなら、そもそもビルダーに口論になることはなかったのかもしれません。おそらく「クリーン」なモナドを用意し、get_int などを適切なモジュールに移動して、明示的に HttpContext を引数としてとるようにします。
  3. F# 3.0 以降を使用している場合は、 get_int などをワークフローのカスタム操作として定義できます。これにより、必要な優れた構文が効果的に得られるはずです。これについては、Tomas Petricek による良い記事があります。
  4. 2. と 3. を組み合わせます - 多数のカスタム操作の代わりに、関数askを取り、それに適用するものを 1 つ用意します。事実上、リーダーのろくでなしバージョン。次に、get_int などを適切なモジュールに移動できます。 HttpContext -> 'actx
于 2014-11-13T08:22:06.800 に答える