1

差別化された共用体があるとしましょう。

type foo = Bar | Baz | Batz

次に、リストのメンバーの数を確認したいと思いますBaz

List.sumBy (function Bar -> 1 | _ -> 0) foos

これを行うためのより慣用的な方法はありますか?

4

5 に答える 5

4

例が正しくないことに注意してください。そのはず:

List.sumBy (fun x -> match x with Baz -> 1 | _ -> 0) foos

これは次のように書き直すことができます。

List.sumBy (function Baz -> 1 | _ -> 0) foos

ここで使用するよりも理想的な方法はないと思いList.sumByます。

于 2012-06-02T20:31:43.683 に答える
3

「より慣用的な」をどのように定義するかによって異なります。それが、他の要因の中でもとりわけ、コードのパフォーマンスによって測定された言語能力の同義語である場合、同様に簡潔になります

List.fold (fun sum -> function Baz -> sum + 1 | _ -> sum) 0 foos

List.sumByF#2.0未満のバージョンよりも、実行速度が3〜4倍速いため、慣用的なものと見なされる場合があります。

List.foldの実装はリスト用に特別に最適化されているため、パフォーマンスの格差は非常に大きくなりますが、実装が通常のトラバーサルを通過する場所List.sumByにフォールバックします。Seq.sumByIEnumerable

于 2012-06-03T03:18:26.063 に答える
0

関数を定義しcountます。与えられた述語を満たす要素の数を数えたいというのは、かなり一般的なユースケースです。

let count pred = List.sumBy (fun x -> if pred x then 1 else 0)

使用する:

count (fun x -> x = Bar) foos
于 2012-06-03T19:41:48.633 に答える
0

これは私が本能的にしたことです。フィルタ|>長さは合計や折りたたみよりも自然に見えます。パフォーマンスをチェックしていません。

let count = 
    myList 
        |> List.filter (fun elem -> match elem with | Baz -> true | _ -> false)
        |> List.length
于 2012-06-03T20:14:13.440 に答える
0

...完全を期すために、forループがパターンマッチできるというあまり知られていない事実を忘れないでください。ただし、パターンマッチングが不完全であるという警告が表示されますが、これは煩わしいことです。

open System

type foo = Bar | Baz of int | Batz of string * string

let myList = [Bar; Bar; Baz(1); Batz("x", "y"); Baz(2)]

let count = 
    let mutable acc = 0
    for Baz(_) in myList do
        acc <- acc + 1
acc
于 2012-06-03T20:22:44.400 に答える