Programmazione interattiva con F#
F# Interactive (dotnet fsi) viene usato per eseguire codice F# in modo interattivo nella console o per eseguire script F#. In altre parole, F# interactive esegue un REPL (Read, Evaluate, Print Loop) per F#.
Per eseguire F# Interactive dalla console, eseguire dotnet fsi
. È possibile trovare dotnet fsi
in qualsiasi .NET SDK.
Nota
Se si intende usare F# interactive sotto il runtime di .NET Framework, è necessario avere il Visual Studio Build Tools o un'edizione di Visual Studio installata e richiamare il comando FsiAnyCPU.exe
dal "Prompt dei comandi per sviluppatori" o semplicemente rendere disponibile FsiAnyCPU.exe
nella variabile di ambiente PATH
, al posto dell'opzione da riga di comando dotnet fsi
.
Gli strumenti supportano la definizione della versione del runtime F# Interactive.
- In Visual Studio: nella barra dei menu Strumenti / Opzioni quindi Strumenti F# / F# Interactivee modificare Usare scripting .NET Core.
- In Visual Studio Code (estensione ionide): nella palette dei comandi Preferenze: Apri le impostazioni utente, quindi Estensioni / F# / FSharp: Fsi Sdk File Path.
Per informazioni sulle opzioni della riga di comando disponibili, vedere opzioni interattive F#.
Esecuzione del codice direttamente in F# Interactive
Poiché F# Interactive è un ciclo REPL (read-eval-print), è possibile eseguire il codice in modo interattivo. Di seguito è riportato un esempio di sessione interattiva dopo l'esecuzione di dotnet fsi
dalla riga di comando:
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 = ()
Si noteranno due aspetti principali:
- Tutto il codice deve essere terminato con un doppio punto e virgola (
;;
) per essere valutato. - Il codice viene valutato e archiviato in un valore
it
. È possibile fare riferimentoit
in modo interattivo.
F# Interactive supporta anche l'input su più righe. Devi solo terminare l'invio con un doppio punto e virgola (;;
). Si consideri il frammento di codice seguente incollato e valutato da 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 = ()
>
La formattazione del codice viene mantenuta ed è presente un doppio punto e virgola (;;
) che termina l'input. F# Interactive ha quindi valutato il codice e stampato i risultati.
Programmazione script con F#
La valutazione del codice in modo interattivo in F# Interactive può essere uno strumento di apprendimento ottimale, ma si noterà rapidamente che non è così produttivo come la scrittura di codice in un normale editor. Per supportare la normale modifica del codice, è possibile scrivere script F#.
Gli script usano l'estensione di file .fsx. Anziché compilare il codice sorgente e quindi eseguire l'assembly compilato in un secondo momento, è sufficiente eseguire dotnet fsi e specificare il nome file dello script e F# Interactive legge il codice ed esegue il codice in tempo reale. Si consideri ad esempio lo script seguente denominato Script.fsx
:
let getOddSquares xs =
xs
|> List.filter (fun x -> x % 2 <> 0)
|> List.map (fun x -> x * x)
printfn "%A" (getOddSquares [1..10])
Quando questo file viene creato nel computer, è possibile eseguirlo con dotnet fsi
e visualizzare l'output direttamente nella finestra del terminale:
dotnet fsi Script.fsx
[1; 9; 25; 49; 81]
Esecuzione di script con uno sha-bang
Per rendere eseguibili gli script F# senza richiamare in modo esplicito dotnet fsi
, è possibile usare una riga shebang nella parte superiore dello script. In questo modo è possibile eseguire lo script direttamente dal terminale, ad esempio uno script della shell.
Ad esempio, creare un file di script denominato ExecutableScript.fsx
con il contenuto seguente:
#!/usr/bin/env -S dotnet fsi
let getOddSquares xs =
xs
|> List.filter (fun x -> x % 2 <> 0)
|> List.map (fun x -> x * x)
printfn "%A" (getOddSquares [1..10])
Rendere eseguibile lo script: Usare il comando
chmod
per rendere eseguibile lo script:chmod +x ExecutableScript.fsx
Eseguire direttamente lo script: Ora, è possibile eseguire lo script direttamente dal terminale:
./ExecutableScript.fsx
Nota: la funzionalità Shebang (
#!
) è specifica per sistemi simili a Unix, ad esempio Linux e MacOS. In Windows è possibile eseguire script usandodotnet fsi Script.fsx
direttamente nel terminale o nel prompt dei comandi.
Questa funzionalità consente un'esperienza più semplice quando si lavora con script F# in ambienti come Linux e macOS.
Il supporto nativo dello scripting F# è disponibile in Visual Studio e in Visual Studio Code.
Riferimento ai pacchetti in F# Interactive
Nota
Il sistema di gestione dei pacchetti è estensibile, vedere altre informazioni sui plug-in e sul meccanismo di estensione.
Dalla versione 5.0 del linguaggio, F# Interactive supporta il riferimento ai pacchetti tramite un meccanismo di estendibilità; può fare riferimento ai pacchetti NuGet con la sintassi #r "nuget:"
e una versione facoltativa:
#r "nuget: Newtonsoft.Json"
open Newtonsoft.Json
let data = {| Name = "Don Syme"; Occupation = "F# Creator" |}
JsonConvert.SerializeObject(data)
Se non viene specificata una versione, viene acquisito il pacchetto non di anteprima più alto disponibile. Per fare riferimento a una versione specifica, introdurre la versione tramite una virgola. Questo può essere utile quando si fa riferimento a una versione di anteprima di un pacchetto. Si consideri ad esempio questo script usando una versione di anteprima di 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)}"
Specificare un'origine del pacchetto
È anche possibile specificare un'origine del pacchetto con il comando #i
. L'esempio seguente specifica un'origine remota e locale:
#i "nuget: https://my-remote-package-source/index.json"
#i """nuget: C:\path\to\my\local\source"""
Questo indicherà al motore di risoluzione sotto le quinte di prendere in considerazione anche le origini remote e/o locali aggiunte a uno script.
È possibile specificare il numero di riferimenti al pacchetto desiderato in uno script.
Nota
Attualmente esiste una limitazione per gli script che usano riferimenti al framework (ad esempio,Microsoft.NET.Sdk.Web
o Microsoft.NET.Sdk.WindowsDesktop
). Pacchetti come Saturno, Giraffe, WinForms non sono disponibili. Questo problema viene rilevato nel problema #9417.
WinForms funziona ancora nella versione .NET Framework di F# Interactive.
Per caricare estensioni aggiuntive accanto a quelle fornite con l'SDK e/o con gli strumenti, usare il flag --compilertool:<extensionsfolderpath>
come argomento per la sessione interattiva F# (o nelle impostazioni degli strumenti).
Riferimento agli assemblaggi su disco con F# Interactive
In alternativa, se si dispone di un assembly su disco e si desidera fare riferimento a tale assembly in uno script, è possibile usare la sintassi #r
per specificare un assembly. Si consideri il codice seguente in un progetto compilato in MyAssembly.dll
:
// MyAssembly.fs
module MyAssembly
let myFunction x y = x + 2 * y
Dopo la compilazione, è possibile farvi riferimento in un file denominato Script.fsx
simile al seguente:
#r "path/to/MyAssembly.dll"
printfn $"{MyAssembly.myFunction 10 40}"
L'output è il seguente:
dotnet fsi Script.fsx
90
È possibile specificare il numero di riferimenti agli assembly desiderati in uno script.
Caricamento di altri script
Quando si esegue lo script, spesso può essere utile usare script diversi per attività diverse. In alcuni casi può essere necessario riutilizzare il codice da uno script in un altro. Anziché copiarne il contenuto nel file, è sufficiente caricarlo e valutarlo con #load
.
Si considerino i Script1.fsx
seguenti:
let square x = x * x
E il file di consumo, Script2.fsx
:
#load "Script1.fsx"
open Script1
printfn $"%d{square 12}"
È possibile valutare Script2.fsx
come segue:
dotnet fsi Script2.fsx
144
È possibile specificare il numero di direttive #load
desiderate in uno script.
Nota
La dichiarazione di open Script1
è obbligatoria. Ciò è dovuto al fatto che i costrutti in uno script F# vengono compilati in un modulo di primo livello che corrisponde al nome del file di script in cui si trova. Se il file di script ha un nome minuscolo, ad esempio script3.fsx
, il nome del modulo implicito viene automaticamente in maiuscolo e sarà necessario usare open Script3
. Se desideri che uno script caricabile definisca costrutti in uno spazio dei nomi specifico del modulo, puoi includere una dichiarazione dello spazio dei nomi del modulo, ad esempio:
module MyScriptLibrary
Uso dell'oggetto fsi
nel codice F#
Gli script F# hanno accesso a un oggetto fsi
personalizzato che rappresenta la sessione F# Interactive. Consente di personalizzare elementi come la formattazione dell'output. È anche possibile accedere agli argomenti della riga di comando.
L'esempio seguente illustra come ottenere e usare argomenti della riga di comando:
let args = fsi.CommandLineArgs
for arg in args do
printfn $"{arg}"
Quando viene valutata, stampa tutti gli argomenti. Il primo argomento è sempre il nome dello script valutato:
dotnet fsi Script1.fsx hello world from fsi
Script1.fsx
hello
world
from
fsi
È anche possibile usare System.Environment.GetCommandLineArgs()
per accedere agli stessi argomenti.
Informazioni di riferimento sulle direttive F# Interactive
Le direttive #r
e #load
viste in precedenza sono disponibili solo in F# Interactive. In F# Interactive sono disponibili diverse direttive:
Direttiva | Descrizione |
---|---|
#r "nuget:..." |
Fa riferimento a un pacchetto da NuGet |
#r "extname:..." |
Fare riferimento a un pacchetto dall'estensione extname [^1] (ad esempio paket ) |
#r "assembly-name.dll" |
Fa riferimento a un assembly su disco |
#load "file-name.fsx" |
Legge un file di origine, lo compila ed esegue il file. |
#help |
Visualizza informazioni sulle direttive o la documentazione disponibili per funzioni specifiche. |
#I |
Specifica un percorso di ricerca di assembly tra virgolette. |
#quit |
Termina una sessione di F# Interactive. |
#time on o #time off |
Da sé, #time attiva o disattiva la visualizzazione delle informazioni sulle prestazioni. Quando è on , F# Interactive misura il tempo reale, il tempo CPU e la raccolta dei rifiuti per ogni sezione del codice interpretato ed eseguito. |
[^1]: Altre informazioni sulle estensioni interattive F# .
Quando si specificano file o percorsi in F# Interactive, è prevista una stringa letterale. Pertanto, i file e i percorsi devono essere tra virgolette e si applicano i caratteri di escape consueti. È possibile usare il carattere @
per fare in modo che F# Interactive interpreti una stringa contenente un percorso come stringa verbatim. In questo modo F# Interactive ignora tutti i caratteri di escape.
Per altri casi, le virgolette sono facoltative, a partire da F# 9.
Direttiva #help estesa
La direttiva #help
supporta ora la visualizzazione della documentazione per funzioni specifiche. È possibile passare direttamente il nome della funzione per recuperare i dettagli.
#help List.map;;
L'output è il seguente:
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
Questo miglioramento semplifica l'esplorazione e la comprensione interattiva delle librerie F#.
Per ulteriori dettagli, consultare il devblog ufficiale .
Direttive del preprocessore interattive e compilate
Quando si compila codice in F# Interactive, sia eseguendolo in modo interattivo sia eseguendo uno script, viene definito il simbolo INTERACTIVE. Quando si compila il codice nel compilatore, il simbolo COMPILED viene definito. Pertanto, se il codice deve essere diverso nelle modalità compilate e interattive, è possibile usare queste direttive del preprocessore per la compilazione condizionale per determinare quale usare. Per esempio:
#if INTERACTIVE
// Some code that executes only in FSI
// ...
#endif
Uso di F# Interactive in Visual Studio
Per eseguire F# Interactive tramite Visual Studio, è possibile fare clic sul pulsante della barra degli strumenti appropriato con etichetta F# Interactiveoppure usare i tasti CTRL+ALT+F. In questo modo si aprirà la finestra interattiva, una finestra degli strumenti che esegue una sessione F# Interactive. È anche possibile selezionare un codice da eseguire nella finestra interattiva e premere la combinazione di tasti ALT+INVIO. F# Interactive viene avviato in una finestra degli strumenti con etichetta F# Interactive. Quando si usa questa combinazione di tasti, assicurarsi che la finestra dell'editor abbia lo stato attivo.
Indipendentemente dal fatto che si usi la console o Visual Studio, viene visualizzato un prompt dei comandi e l'interprete attende l'input. È possibile immettere il codice esattamente come in un file di codice. Per compilare ed eseguire il codice, immettere due punti e virgola (;;) per terminare una riga o più righe di input.
F# Interactive tenta di compilare il codice e, se ha esito positivo, esegue il codice e stampa la firma dei tipi e dei valori compilati. Se si verificano errori, l'interprete stampa i messaggi di errore.
Il codice immesso nella stessa sessione ha accesso a tutti i costrutti immessi in precedenza, in modo da poter creare programmi. Un buffer esteso nella finestra degli strumenti consente di copiare il codice in un file, se necessario.
Quando viene eseguito in Visual Studio, F# Interactive viene eseguito indipendentemente dal progetto, quindi, ad esempio, non è possibile usare costrutti definiti nel progetto in F# Interactive a meno che non si copia il codice per la funzione nella finestra interattiva.
È possibile controllare gli argomenti della riga di comando di F# Interactive (opzioni) modificando le impostazioni. Nel menu Strumenti, selezionare Opzioni..., e quindi espandere F# Strumenti. Le due impostazioni che è possibile modificare sono le opzioni F# Interactive e l'impostazione interattiva F# a 64 bit, che è rilevante solo se si esegue F# Interactive in un computer a 64 bit. Questa impostazione determina se si vuole eseguire la versione dedicata a 64 bit di fsi.exe o fsianycpu.exe, che usa l'architettura del computer per determinare se eseguire come processo a 32 bit o a 64 bit.
Articoli correlati
Titolo | Descrizione |
---|---|
opzioni interattive F# | Descrive la sintassi della riga di comando e le opzioni per F# Interactive fsi.exe. |