プレビュー版として提供されているF# 4.5では、いくつもの新しい機能が提供されている。例えば、.NET Core 2.1のサポート、プリミティブ型の Span<T> 、新しいキーワード Match! などだ。

Spanはポインタの操作の低いレベルのコードを安全で予測可能にする。これによってメモリの確保の必要性を削減しメモリの効率的にし性能を改善する。Spanはすでにメモリのどこかに保存されているデータの仮想的なビューを提供する。例えば、10000の要素の配列がある場合、最初の1000の要素を含むスライスを仮想的に作成し、コピーを作成せずにそれを関数に渡すことができる。

let nativeMemory = Marshal.AllocHGlobal(100); let nativeSpan = new Span<byte>(nativeMemory.ToPointer(), 100) let nativeSpanSlice = new Span<byte>(nativeMemory.ToPointer(), 10) let mem = NativePtr.stackalloc<byte>(100) let mem2 = mem |> NativePtr.toVoidPtr let stackSpan = Span<byte>(mem2, 100)

実際には、Spanには複数の機能が含まれている。 voidptr 型、 NativePtr.ofVoidPtr 、 NativePtr.toVoidPtr 関数などだ。これらがF# 4.5のSpanのサポートをC# 7.3と同等のものにしている。対応関係は以下の通りだ。

C# F# out int arg arg: byref<int> out int arg arg: outref<int> in int arg arg: inref<int> ref readonly int Inferred or arg: inref<int> ref expr &expr

コードの安定性を保証するため、F#はSpanの利用にいくつかの制限がある。どれも、 byref ライクな構造体に適用される。

let で束縛された値はその参照を宣言されたスコープから外に出せない。

で束縛された値はその参照を宣言されたスコープから外に出せない。 byref ライクな構造体はインスタンス化できない。クラスや普通の構造体の静的なメンバになれない。

ライクな構造体はインスタンス化できない。クラスや普通の構造体の静的なメンバになれない。 byref ライクな構造体はジェネリックな型パラメータとして使えない。

ライクな構造体はジェネリックな型パラメータとして使えない。 byref ライクな構造体はクロージャでは捕捉できない。

Match! キーワードは開発者にとって待望の新機能であり、コンピュテーション式内のマッチング構文を単純にする。F# 4.1では、マッチングの前段として let! を使う必要があった。

let funcWithString (s: string) = async { let! r = asyncFunction s match r with | Some bananaString -> printfn "It's banana!" | None -> printfn "%s" s }

F# 4.5では、単純に次のように書ける。

let funcWithString (s: string) = async { match! asyncFunction s with | Some bananaString -> printfn "It's banana!" | None -> printfn "%s" s }

また、F# 4.5には次のような機能も含まれる。

yield をシーケンス、リスト、配列で使ったとき、アップキャストが必要なくなる。

let x2 : obj list = [ yield "a" :> obj ] // pre-F# 4.5 let x3 : obj list = [ yield "a" ] // F# 4.5

列挙型はデフォルトでパブリックとして出力される。プロファイルツールを利用しやすくするため。

Asyncのスタックトレースの改善。有用な情報を提供する。

F# 4.5はプレビューであるものの、とても安定しており、Visual Studio 2017 update 15.8に同梱される予定。それまでの間は、.NET core プラットフォームとWindowsで入手できる。