2017-01-31 3 views
6

現在、私はこのパターンを使用します。さまざまな種類の多くの「結果」を簡潔に組み合わせることはできますか?

let a: Result<A, ParseError> = parseA(); 
let b: Result<B, ParseError> = parseB(); 
let c: Result<C, ParseError> = parseC(); 
a.and_then(|a| b.map(|b| (a, b))).and_then(|(a,b)| c.map(|c| { 
    // finally the crux of what I want to do 
    a.foo(b).bar(c) 
})) 

は、Scalaのための式として、ab & cを定義するために、より簡潔な方法はありますか?

+1

ここにしようとしているように、これは正確には「結果を結合する」というわけではありません。しかし、最近私はこれを行っています。すべてをまとめて解析すると、解析が行われます(http://play.integer32 .com /?gist = 9470f7e9f293852f7444c1017ae91fa9&version = stable)。私はこのシナリオで失敗したものがあれば、それがはるかに難しいことを考えれば、これがあなたに適しているかどうかは分かりません。 –

+0

私はそれが好きです。それは私が必要とするものではありませんが、私の質問が少し誤解を招くことに気づかせてくれます。私はそれを書いて別のものを持っていきます。 – Synesso

答えて

3

私は通常の代わりにタプルを通じて、連鎖の層のすべてを包む:

let result = a.and_then(|a| { 
    b.and_then(|b| { 
     c.map(|c| { 
      a.foo(b).bar(c) 
     }) 
    }) 
}); 

それとも、最近の錆のバージョンでは、あなたが?オペレータの精巧な利用を行うことができます。

let result = a.and_then(|a| { 
    a.foo(b?).bar(c?) 
}); 

クロージャはあなたを許しますこれをきれいに、安全に行う。

中間にResultを変数に格納する場合は、もちろんこれは機能しません。

+0

「?foo(b?)。bar(c?)」も使えませんか?あるいは、 'parseA()?foo(parseB()?)bar。(parseC()?)'であり、 'parseA'が失敗した場合は' parseB'を実行しません。 – user4815162342

+2

関数が 'Result'を返す場合のみです。手動で処理したい場合は、手動で処理する必要があります。あなたが 'Result'を返すとしても、あなたは' 'Ok(a?.foo(b?))と' 'a.and_then(| a | a.foo(b?))」の間で決める必要があります。実際のコードは、後者をより読みやすくすることがあります(serdeでは、この状況が頻繁にあります)。 –

関連する問題