14

私は、これらのルールに従ってResult<'T, 'E> listシングルにしたいを持っています:Result<'T list, 'E>

  • いずれかResultが のError場合、結果はError
  • 結果が の場合、リストErrorの最初にある必要がありますError
  • すべての結果が である場合OK、結果は でOkあり、リストの順序を維持する必要があります

だから私は行って、これを次のように実装しました:

let all xs = 
  let folder = fun state next -> 
    match (state, next) with 
    | (Result.Ok ys, Result.Ok y) -> ys |> List.append [ y ] |> Result.Ok
    | (Result.Error e, _) -> Result.Error e 
    | (_, Result.Error e) -> Result.Error e 
  Seq.fold folder (Result.Ok []) xs

ただし、これは標準ライブラリに既に実装されている可能性があるもののようです。ありますか?

Result次に、次のような計算式があります。

type ResultBuilder () = 
  member this.Bind(x, f) = 
    match x with 
    | Result.Ok o -> f o
    | Result.Error e -> Result.Error e
  member this.Return(value) = Result.Ok value
  member this.ReturnFrom(value) = value

let result = new ResultBuilder()

all内部で使用できますresult { ... }が、さらに統合することは可能ですか? たとえば、ResultBuilder.For?

4

4 に答える 4

10

あなたは を持っていて、Result<'a, 'e> listを欲しがっていResult<'a list, 'e>ます。これは、 https://fsharpforfunandprofit.com/posts/elevated-world-4/sequenceで説明されている関数のように聞こえます(名前のように聞こえますが、s とは関係ありません)。https://github.com/fsharp/fsharp/blob/master/src/fsharp/FSharp.Core/result.fsを簡単に確認すると、この関数は標準の FSharp.Core ライブラリに実装されていないことがわかります。自分で実装する必要があります。seq

ところで、Scott Wlaschin の「Elevated World」シリーズをまだ読んでいない場合は、リンクした記事の途中から始めることはお勧めしません。代わりに、この記事から始めてください。「トラバース」機能と「シーケンス」機能の機能を理解するために必要な背景知識を構築するためです。次に、それらの関数の 1 つを実装するための一般的なパターンを理解します。

2 番目の質問ですが、もう少し具体的に教えていただけますか。たとえば、 からどのような動作が必要ですResultBuilder.Forか? 式に期待される通常の動作はfor、(または seq または配列) を取り、リスト、seq、または配列にあるResult<'a, 'e> listすべてのブロックに対して 1 回内側のブロックを実行することです。Result<'a, 'e>ここで関数を使用しようとすると、(F# が CE のメソッドが生成することを期待するもの) とメソッドが返すものとのall間に型の不一致が生じます。メソッドで具体的に何をしたいですか?Result<'a, 'e>.ForResult<'a list, 'e>allResultBuilder.For

于 2018-06-11T00:51:56.330 に答える