F を使用した対話型プログラミング#
F# Interactive (dotnet fsi) は、コンソールで F# コードを対話形式で実行したり、F# スクリプトを実行したりするために使用されます。 つまり、F# 対話型では、F# の REPL (読み取り、評価、印刷ループ) が実行されます。
コンソールから F# Interactive を実行するには、dotnet fsi
を実行します。 任意の .NET SDK に dotnet fsi
があります。
手記
.NET Framework ランタイムで F# 対話型を使用する場合は、Visual Studio Build Tools または Visual Studio のエディションがインストールされている必要があります。また、コマンド ラインの代わりに、FsiAnyCPU.exe
コマンドを "開発者コマンド プロンプト" から呼び出すか、PATH
環境変数で FsiAnyCPU.exe
dotnet fsi
使用できるようにする必要があります。
ツールでは、バージョン F# 対話型ランタイムの定義がサポートされています。
- Visual Studio: メニュー バーで [ツール] / [オプション]、[F# ツール] / [F# インタラクティブ] の順に移動し、[.NET Core スクリプトを使用] を調整します。
- Visual Studio Code (ionide 拡張機能): コマンド パレットで、[ユーザー設定: ユーザー設定を開く]、[拡張機能] / [F#] / [FSharp: Fsi Sdk ファイル パス] の順に移動します。
使用可能なコマンド ライン オプションの詳細については、「F# 対話型オプションの」を参照してください。
F# Interactive で直接コードを実行する
F# Interactive は REPL (read-eval-print ループ) であるため、コードを対話形式で実行できます。 コマンド ラインから dotnet fsi
を実行した後の対話型セッションの例を次に示します。
Microsoft (R) F# Interactive version 11.0.0.0 for F# 5.0
Copyright (c) Microsoft Corporation. All Rights Reserved.
For help type #help;;
> let square x = x * x;;
val square : x:int -> int
> square 12;;
val it : int = 144
> printfn "Hello, FSI!"
- ;;
Hello, FSI!
val it : unit = ()
次の 2 つの主な点に気付くでしょう。
- 評価するには、すべてのコードを二重セミコロン (
;;
) で終了する必要があります - コードが評価され、
it
値に格納されます。it
を対話形式で参照できます。
F# Interactive では、複数行入力もサポートされています。 提出を終了するには、二重セミコロン (;;
) を使用するだけです。 F# Interactive によって貼り付けおよび評価された次のスニペットについて考えてみましょう。
> let getOddSquares xs =
- xs
- |> List.filter (fun x -> x % 2 <> 0)
- |> List.map (fun x -> x * x)
-
- printfn "%A" (getOddSquares [1..10]);;
[1; 9; 25; 49; 81]
val getOddSquares : xs:int list -> int list
val it : unit = ()
>
コードの書式設定は保持され、入力を終了する二重セミコロン (;;
) があります。 F# Interactive でコードが評価され、結果が出力されました。
F# を使用したスクリプト
F# Interactive で対話形式でコードを評価することは優れた学習ツールですが、通常のエディターでコードを記述するほど生産性が高くないことがわかります。 通常のコード編集をサポートするために、F# スクリプトを記述できます。
スクリプトでは、.fsxScript.fsx
と呼ばれる次のスクリプトを考えてみましょう。
let getOddSquares xs =
xs
|> List.filter (fun x -> x % 2 <> 0)
|> List.map (fun x -> x * x)
printfn "%A" (getOddSquares [1..10])
このファイルがコンピューターに作成されたら、dotnet fsi
を使用して実行し、ターミナル ウィンドウに出力を直接表示できます。
dotnet fsi Script.fsx
[1; 9; 25; 49; 81]
F# スクリプトは、
F# Interactive でのパッケージの参照
手記
パッケージ管理システムは拡張可能です、プラグインと拡張メカニズムの詳細については、を参照してください。
言語の 5.0 リリース以降、F# インタラクティブでは拡張メカニズムを通じたパッケージの参照がサポートされています。デフォルトで、#r "nuget:"
構文と省略可能なバージョンで NuGet パッケージを参照できます。
#r "nuget: Newtonsoft.Json"
open Newtonsoft.Json
let data = {| Name = "Don Syme"; Occupation = "F# Creator" |}
JsonConvert.SerializeObject(data)
バージョンが指定されていない場合は、使用可能な最高のプレビュー以外のパッケージが取得されます。 特定のバージョンを参照するには、コンマを使用してバージョンを導入します。 これは、パッケージのプレビュー バージョンを参照するときに便利です。 たとえば、DiffSharpのプレビュー バージョンを使用する次のスクリプトを考えてみましょう。
#r "nuget: DiffSharp-lite, 1.0.0-preview-328097867"
open DiffSharp
// A 1D tensor
let t1 = dsharp.tensor [ 0.0 .. 0.2 .. 1.0 ]
// A 2x2 tensor
let t2 = dsharp.tensor [ [ 0; 1 ]; [ 2; 2 ] ]
// Define a scalar-to-scalar function
let f (x: Tensor) = sin (sqrt x)
printfn $"{f (dsharp.tensor 1.2)}"
パッケージ ソースの指定
#i
コマンドを使用してパッケージ ソースを指定することもできます。 次の例では、リモート ソースとローカル ソースを指定します。
#i "nuget: https://my-remote-package-source/index.json"
#i """nuget: C:\path\to\my\local\source"""
これにより、スクリプトに追加されたリモート ソースやローカル ソースも考慮するように、内部の解決エンジンに指示されます。
スクリプトでは、必要な数のパッケージ参照を指定できます。
手記
現在、フレームワーク参照を使用するスクリプトには制限があります (Microsoft.NET.Sdk.Web
や Microsoft.NET.Sdk.WindowsDesktop
など)。 サターン、キリン、WinForms などのパッケージは使用できません。 これは問題 #9417で追跡されています。
WinForms は、F# Interactive の .NET Framework バージョンで引き続き機能します。
SDK やツールに付属する拡張機能の他に追加の拡張機能を読み込むには、F# 対話型セッション (またはツール設定) の引数として --compilertool:<extensionsfolderpath>
フラグを使用します。
F# 対話型でディスク上のアセンブリを参照する
または、ディスク上にアセンブリがあり、スクリプトでそのアセンブリを参照する場合は、#r
構文を使用してアセンブリを指定できます。 MyAssembly.dll
にコンパイルされたプロジェクトの次のコードについて考えてみましょう。
// MyAssembly.fs
module MyAssembly
let myFunction x y = x + 2 * y
コンパイル後は、次のように Script.fsx
というファイルで参照できます。
#r "path/to/MyAssembly.dll"
printfn $"{MyAssembly.myFunction 10 40}"
出力は次のとおりです。
dotnet fsi Script.fsx
90
スクリプトでは、必要な数のアセンブリ参照を指定できます。
他のスクリプトの読み込み
スクリプトを作成するときは、多くの場合、タスクごとに異なるスクリプトを使用すると便利です。 あるスクリプトのコードを別のスクリプトで再利用したい場合があります。 その内容をファイルにコピーして貼り付けるのではなく、#load
で読み込んで評価するだけです。
次の Script1.fsx
について考えてみましょう。
let square x = x * x
また、これを使用するファイル Script2.fsx
があります。
#load "Script1.fsx"
open Script1
printfn $"%d{square 12}"
次のように Script2.fsx
評価できます。
dotnet fsi Script2.fsx
144
スクリプトでは、必要な数の #load
ディレクティブを指定できます。
手記
open Script1
宣言が必要です。 これは、F# スクリプト内のコンストラクトが、それが含まれるスクリプト ファイルの名前である最上位モジュールにコンパイルされるためです。 スクリプト ファイルに script3.fsx
などの小文字の名前がある場合、暗黙的なモジュール名は自動的に大文字になり、open Script3
を使用する必要があります。 loadable スクリプトを使用してモジュールの特定の名前空間でコンストラクトを定義する場合は、モジュール宣言の名前空間を含めることができます。次に例を示します。
module MyScriptLibrary
F# コードでの fsi
オブジェクトの使用
F# スクリプトは、F# 対話型セッションを表すカスタム fsi
オブジェクトにアクセスできます。 これにより、出力の書式設定などをカスタマイズできます。 また、コマンドライン引数にアクセスする方法もあります。
次の例は、コマンド ライン引数を取得して使用する方法を示しています。
let args = fsi.CommandLineArgs
for arg in args do
printfn $"{arg}"
評価されると、すべての引数が出力されます。 最初の引数は、常に評価されるスクリプトの名前です。
dotnet fsi Script1.fsx hello world from fsi
Script1.fsx
hello
world
from
fsi
System.Environment.GetCommandLineArgs()
を使用して、同じ引数にアクセスすることもできます。
F# インタラクティブのディレクティブのリファレンス
前に示した #r
ディレクティブと #load
ディレクティブは、F# Interactive でのみ使用できます。 F# Interactive でのみ使用できるディレクティブがいくつかあります。
指令 | 説明 |
---|---|
#r "nuget:..." |
NuGet からパッケージを参照する |
#r "extname:..." |
extname 拡張機能 [^1] からパッケージを参照する (paket など) |
#r "assembly-name.dll" |
ディスク上のアセンブリを参照する |
#load "file-name.fsx" |
ソース ファイルを読み取り、コンパイルして実行します。 |
#help |
特定の関数の使用可能なディレクティブまたはドキュメントに関する情報を表示します。 |
#I |
アセンブリ検索パスを引用符で囲んで指定します。 |
#quit |
F# Interactive セッションを終了します。 |
#time on または #time off |
#time 単独では、パフォーマンス情報を表示するかどうかを切り替えます。 on の場合には、F# Interactive は、解釈および実行されるコードの各セクションについて、リアルタイム、CPU 時間、およびガベージ コレクションの情報を測定します。 |
[^1]: F# 対話型拡張機能について詳しく説明します。
F# Interactive でファイルまたはパスを指定する場合は、文字列リテラルが必要です。 したがって、ファイルとパスは引用符で囲む必要があり、通常のエスケープ文字が適用されます。 @
文字を使用すると、F# Interactive でパスを含む文字列を逐語的な文字列として解釈できます。 これにより、F# Interactive はエスケープ文字を無視します。
それ以外の場合、F# 9 以降では引用符は省略可能です。
拡張 #help ディレクティブ
#help
ディレクティブは、特定の関数のドキュメントの表示をサポートするようになりました。 関数の名前を直接渡して、詳細を取得できます。
#help List.map;;
出力は次のとおりです。
Description:
Builds a new collection whose elements are the results of applying the given function
to each of the elements of the collection.
Parameters:
- mapping: The function to transform elements from the input list.
- list: The input list.
Returns:
The list of transformed elements.
Examples:
let inputs = [ "a"; "bbb"; "cc" ]
inputs |> List.map (fun x -> x.Length)
// Evaluates to [ 1; 3; 2 ]
Full name: Microsoft.FSharp.Collections.ListModule.map
Assembly: FSharp.Core.dll
この機能強化により、F# ライブラリを対話形式で簡単に調べ、理解できるようになります。
詳細については、公式 devblogを参照してください。
対話型およびコンパイル済みのプリプロセッサ ディレクティブ
F# Interactive でコードをコンパイルする場合、対話形式で実行する場合でもスクリプトを実行する場合でも、INTERACTIVE
#if INTERACTIVE
// Some code that executes only in FSI
// ...
#endif
Visual Studio での F# Interactive の使用
Visual Studio で F# Interactive を実行するには、F# 対話型
コンソールと Visual Studio のどちらを使用しているかに関係なく、コマンド プロンプトが表示され、インタープリターが入力を待機します。 コード ファイルの場合と同様に、コードを入力できます。 コードをコンパイルして実行するには、2 つのセミコロン (;;) を入力して、1 行または複数行の入力を終了します。
F# Interactive はコードのコンパイルを試み、成功した場合はコードを実行し、コンパイルした型と値のシグネチャを出力します。 エラーが発生した場合、インタープリターはエラー メッセージを出力します。
同じセッションに入力されたコードは、前に入力したコンストラクトにアクセスできるため、プログラムをビルドできます。 ツール ウィンドウ内の広範なバッファーを使用すると、必要に応じてコードをファイルにコピーできます。
Visual Studio で実行すると、F# Interactive はプロジェクトとは別に実行されるため、たとえば、関数のコードを対話型ウィンドウにコピーしない限り、F# Interactive でプロジェクトで定義されたコンストラクトを使用することはできません。
設定を調整することで、F# Interactive コマンド ライン引数 (オプション) を制御できます。 [
関連記事
タイトル | 説明 |
---|---|
F# 対話型オプション | F# Interactive、fsi.exeのコマンド ライン構文とオプションについて説明します。 |
.NET