Open3

Fun Fan F#

midoliymidoliy

F# 9.0 New Features

Release notes 9.0

Pick up

Speed up for x in xs -> … in list & array comprehensions in certain scenarios.

Pull Request #16948

Array.map や List.map の糖衣構文だったものを、while に展開することで高速化を図ったとのこと。
実際、めちゃくちゃ早くなってる。

Job Categories Mean Error StdDev Ratio Gen0 Gen1 Gen2 Allocated Alloc Ratio
Current [ 1..100_000 ],ComputedCollections,Arrays,For 1,063,832.9 ns 7,594.63 ns 7,104.02 ns 1.00 35.1563 35.1563 35.1563
Preview [ 1..100_000 ],ComputedCollections,Arrays,For 257,712.2 ns 14,550.04 ns 42,901.11 ns 0.28 5.3711 5.3711 5.3711
Current [ 1..10_000 ],ComputedCollections,Arrays,For 42,213.9 ns 209.39 ns 163.48 ns 1.00 0.6714 0.0610 -
Preview [ 1..10_000 ],ComputedCollections,Arrays,For 4,076.9 ns 37.29 ns 34.88 ns 0.10 0.1602 - -
Current [ 1..1_000_000 ],ComputedCollections,Arrays,For 7,616,795.5 ns 139,302.01 ns 123,487.61 ns 1.00 156.2500 156.2500 156.2500
Preview [ 1..1_000_000 ],ComputedCollections,Arrays,For 1,898,152.2 ns 37,795.17 ns 49,144.40 ns 0.25 56.6406 56.6406 56.6406
Current [ 1..1_000 ],ComputedCollections,Arrays,For 4,104.8 ns 24.64 ns 20.58 ns 1.00 0.0458 - -
Preview [ 1..1_000 ],ComputedCollections,Arrays,For 619.2 ns 4.87 ns 4.56 ns 0.15 0.0162 - -

Lower integral ranges to fast loops in more cases and optimize list and array construction from ranges.

Pull Request #16650
Pull Request #16832

これも List や Array の初期化で IEnumerable<'T> 使ってたせいで低速だったものを高速化させたもの。


Make .Tag and .Is* discriminated union properties visible from F#

Pull Request #222

DU で type Foo = A | B みたいなのを作ったとして、Foo の配列だったりリストだったりを fitler するとき、xs |> List.filter (function A -> true | _ -> false) みたいに無名関数を書くのが面倒くさい。
そもそも内部では IsA とか IsB とかが自動で生成されるんだから、それを使わせてよ。というやつ。

これのおかげで、以下みたいに書けるようになった。

> type Foo = A | B;;                 
type Foo =
  | A
  | B

> let xs = [| A; B; A |];;           
val xs: Foo array = [|A; B; A|]

> let ys = xs |> Array.filter _.IsA;;
val ys: Foo array = [|A; A|]

Allow returning bool instead of unit option for partial active patterns

Pull Request #1041
Pull Request #16473

部分的なアクティブ パターンの戻り値について、Option<'T> だけではなく bool も許容されるようになった。

これにより、今まで以下のようにわざわざ Some () / None を返していたような処理が、よりすっきりと書けるようになる。

> let (|Odd|_|) x = if x % 2 = 1 then Some () else None;;
val (|Odd|_|) : x: int -> unit option

> match 3 with Odd _ -> printfn "Odd" | _ -> printfn "Even";;
Odd
val it: unit = ()
> let (|Odd|_|) x = x % 2 = 1;;                              
val (|Odd|_|) : x: int -> bool

> match 3 with Odd -> printfn "Odd" | _ -> printfn "Even";;  
Odd
val it: unit = ()