2015-10-05 5 views
10

in`ため `における労働組合のコンストラクタのパターンマッチを...と、私はこのような値を組合のリストを入力した場合:私はすべて抽出するために小さな「トリック」を使用することができどのようにHaskellで

example :: [Either Int Char] 
example = [Left 3, Right 'b', Left 6, Left 9, Right 'c'] 

いくつかの特定のパターンに一致する結果は:

let lefts = [for Choice1Of2 l in example -> l] 
       ~~~~~~~~~~~~ 
Incomplete pattern matches on this expression. (...) 

この:私はF#1にこれを翻訳しようとした場合

lefts :: [Int] 
lefts = [l | Left l <- example] 

しかし、私はエラーを取得します/多くの意味になります(それも黙ってHaskellのようなRight値をん無視してより良い行動かもしれません!)が、F#で、抽出(とで一致)するためにいくつかの便利な方法があり、リスト内の特定のパターンに一致するすべての値シーケンス

答えて

16

F#では、あなたはすべてのシナリオでは、警告を取得しますすべてのケースに対して一致しない場合。

だから、式の内側両方のケースで試合を書き込むことができますが、あなたの例ではなく、内包のために私は機能List.choose使用します。この機能は、これらの例に便利です

let example = [Choice2Of2 3; Choice1Of2 'b'; Choice2Of2 6; Choice2Of2 9; Choice1Of2 'c'] 
List.choose (function (Choice1Of2 x) -> Some x | _ -> None) example 
// val it : char list = ['b'; 'c'] 

を。

12

私はあなたがF#のリスト式を使用して行うことができます最も近いものは、このようなものだと思う:私が正しくHaskellコードを理解していれば、|後の部分がないだけで、抽出に使用される

let lefts example = 
    [ for e in example do 
     match e with Choice1Of2 l -> yield l | _ ->() ] 

、だけでなく、フィルタとして - パターンと一致しないすべてのものを暗黙的にスキップします。

F#がリスト式に概念の同じ種類を持っていないので、あなたはより冗長でなければなりません。ここで、私たちはforを使用して以上のすべてのアイテムを反復し、我々は明示的に(と私たちは何かを飛ばし)ソースリスト内の各Choice1Of2の新しい値を生成するためにyieldを使用しています。 (グスタボの答えで述べたように)

あなたがList.chooseを使用して、やっていることに応じて、より簡単かもしれません。しかし、上記おそらくあなたはHaskellの理解構文に得ることができる最も近いです。

関連する問題