Programación interactiva con F#
F# interactivo (dotnet fsi) se utiliza para ejecutar código de F# de manera interactiva en la consola o para ejecutar scripts de F#. En otras palabras, F# Interactive ejecuta un bucle REPL (del inglés Read, Evaluate, Print Loop - bucle Leer, Evaluar, Imprimir) para F#.
Para ejecutar F# interactivo desde la consola, ejecute dotnet fsi
. Encontrará dotnet fsi
en cualquier SDK de .NET.
Nota:
Si tiene intención de utilizar F# interactivo en tiempo de ejecución de .NET Framework, necesitará tener instalado Visual Studio Build Tools o una edición de Visual Studio, e invocar el comando FsiAnyCPU.exe
desde un "Símbolo del sistema para desarrolladores" o simplemente poner FsiAnyCPU.exe
a disposición en la variable de entorno PATH
, en lugar de la línea de comandos dotnet fsi
.
Las herramientas permiten definir la versión F# Interactive runtime:
- En Visual Studio: en la barra de menús, Herramientas / Opciones luego Herramientas de F# / F# Interactive y ajuste Usar scripting de .NET Core.
- En Visual Studio Code (extensión ionide): en la paleta de comandos, Preferencias: Abre lasConfiguraciones de usuario y, a continuación, Extensiones / F# / FSharp: ruta del archivo del SDK de Fsi.
Para obtener más información sobre las opciones de línea de comandos disponibles, vea Opciones de F# interactivo.
Ejecución del código directamente en F# interactivo
Dado que F# interactivo es un REPL (read–eval–print loop), puede ejecutar el código en él de forma interactiva. Este es un ejemplo de una sesión interactiva después de ejecutar dotnet fsi
desde la línea de comandos:
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 = ()
Observará dos cuestiones principales:
- Todo el código debe terminar con un punto y coma doble (
;;
) para ser evaluado. - El código se evalúa y se almacena en un valor
it
. Puede hacer referencia ait
de forma interactiva.
F# interactivo también admite la entrada de varias líneas. Solo tiene que terminar el envío con un punto y coma doble (;;
). Observe el siguiente fragmento de código que se ha pegado en F# interactivo para su evaluación:
> 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 = ()
>
Se conserva el formato del código, y la entrada termina con un punto y coma doble (;;
). F# interactivo evaluó el código e imprimió los resultados.
Scripting con F#
La evaluación del código de forma interactiva en F# interactivo puede ser una magnífica herramienta de aprendizaje, pero se dará cuenta rápidamente de que no es tan productivo como escribir código en un editor normal. Para admitir la edición normal de código, puede escribir scripts de F#.
Los scripts usan la extensión de archivo .fsx. En lugar de compilar código fuente y, después, ejecutar el ensamblado compilado, simplemente puede ejecutar dotnet fsi y especificar el nombre de archivo del script y F# Interactive lee el código y lo ejecuta en tiempo real. Por ejemplo, vamos a analizar el siguiente script llamado Script.fsx
:
let getOddSquares xs =
xs
|> List.filter (fun x -> x % 2 <> 0)
|> List.map (fun x -> x * x)
printfn "%A" (getOddSquares [1..10])
Cuando este archivo se crea en el equipo, puede ejecutarlo con dotnet fsi
y ver la salida directamente en la ventana de terminal:
dotnet fsi Script.fsx
[1; 9; 25; 49; 81]
Ejecución de scripts con un shebang
Para que los scripts de F# sean ejecutables sin invocar explícitamente dotnet fsi
, puede usar una línea shebang en la parte superior del script. Esto le permite ejecutar el script directamente desde el terminal, como un script de shell.
Por ejemplo, cree un archivo de script denominado ExecutableScript.fsx
con el siguiente contenido:
#!/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])
Hacer el script ejecutable: Usa el comando
chmod
para hacer el script ejecutable:chmod +x ExecutableScript.fsx
Ejecutar el script directamente: Ahora, puede ejecutar el script directamente desde el terminal:
./ExecutableScript.fsx
Nota: la funcionalidad shebang (
#!
) es específica de sistemas similares a Unix, como Linux y MacOS. En Windows, puede ejecutar scripts mediantedotnet fsi Script.fsx
directamente en el terminal o el intérprete de comandos.
Esta característica permite una experiencia más fluida al trabajar con scripts de F# en entornos como Linux y macOS.
El scripting de F# se admite de forma nativa en Visual Studio y Visual Studio Code.
Referencia a paquetes en F# interactivo
Nota:
El sistema de administración de paquetes es extensible, consulte más sobre los complementos y el mecanismo de extensión.
Desde la versión 5.0 del lenguaje, F# interactivo admite la referencia de paquetes a través de un mecanismo de extensibilidad; de forma predeterminada, puede hacer referencia a paquetes NuGet con la sintaxis #r "nuget:"
y una versión opcional:
#r "nuget: Newtonsoft.Json"
open Newtonsoft.Json
let data = {| Name = "Don Syme"; Occupation = "F# Creator" |}
JsonConvert.SerializeObject(data)
Si no se especifica ninguna versión, se usa el paquete más alto disponible que no se encuentra en versión preliminar. Para hacer referencia a una versión concreta, introduzca la versión con una coma. Esto puede ser útil cuando se hace referencia a una versión preliminar de un paquete. Por ejemplo, considere este script mediante una versión preliminar de 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)}"
Especificación del origen de un paquete
También puede especificar el origen de un paquete con el comando #i
. En el ejemplo siguiente, se especifican un origen remoto y uno local:
#i "nuget: https://my-remote-package-source/index.json"
#i """nuget: C:\path\to\my\local\source"""
Esto le indicará al motor de resolución en segundo plano que también tenga en cuenta los orígenes locales o remotos agregados a un script.
Puede especificar tantas referencias de paquete como desee en un script.
Nota:
Actualmente hay una limitación para los scripts que usan referencias de marco (por ejemplo, Microsoft.NET.Sdk.Web
o Microsoft.NET.Sdk.WindowsDesktop
). Los paquetes como Saturno, Giraffe y WinForms no están disponibles. Se está realizando un seguimiento en la incidencia 9417.
WinForms sigue funcionando en la versión de .NET Framework de F# interactivo.
Para cargar extensiones adicionales junto a las que se incluyen con el SDK o con las herramientas, use la marca --compilertool:<extensionsfolderpath>
como argumento para la sesión F# interactiva (o en la configuración de herramientas).
Referencias a ensamblados en el disco con F# interactivo
Como alternativa, si tiene un ensamblado en el disco y desea hacer referencia a él en un script, puede usar la sintaxis #r
para especificar un ensamblado. Considere el siguiente código en un proyecto compilado en MyAssembly.dll
:
// MyAssembly.fs
module MyAssembly
let myFunction x y = x + 2 * y
Tras la compilación, puede hacer referencia a él en un archivo denominado Script.fsx
similar al siguiente:
#r "path/to/MyAssembly.dll"
printfn $"{MyAssembly.myFunction 10 40}"
La salida es como sigue:
dotnet fsi Script.fsx
90
Puede especificar tantas referencias de ensamblado como desee en un script.
Carga de otros scripts
Al crear scripts, a menudo puede ser útil usar diferentes scripts para distintas tareas. En ocasiones, es posible que quiera volver a usar el código de un script en otros. En lugar de copiar y pegar el contenido en tu archivo, simplemente puedes cargarlo y evaluarlo con #load
.
Observe la sintaxis Script1.fsx
siguiente:
let square x = x * x
Y también el uso del archivo Script2.fsx
:
#load "Script1.fsx"
open Script1
printfn $"%d{square 12}"
Puede evaluar Script2.fsx
de una forma similar a la siguiente:
dotnet fsi Script2.fsx
144
Puede especificar tantas directivas #load
como desee en un script.
Nota:
La declaración open Script1
es obligatoria. Esto se debe a que las construcciones de un script de F# se compilan en un módulo de nivel superior cuyo nombre coincide con el del archivo de script en el que está incluido. Si el archivo de script tiene un nombre en minúsculas como script3.fsx
, el nombre del módulo implícito se pone en mayúsculas automáticamente, y deberá utilizar open Script3
. Si desea que un script cargable defina construcciones en un espacio de nombres específico de un módulo, puede incluir una declaración de espacio de nombres del módulo, por ejemplo:
module MyScriptLibrary
Uso del objeto fsi
en el código de F#
Los scripts de F# tienen acceso a un objeto fsi
personalizado que representa la sesión de F# interactivo. Permite personalizar aspectos como el formato de la salida. También define la forma de acceder a los argumentos de la línea de comandos.
En el ejemplo siguiente se muestra cómo usar argumentos de la línea de comandos y la forma de acceder a ellos:
let args = fsi.CommandLineArgs
for arg in args do
printfn $"{arg}"
Cuando se evalúa, imprime todos los argumentos. El primer argumento siempre es el nombre del script que se evalúa:
dotnet fsi Script1.fsx hello world from fsi
Script1.fsx
hello
world
from
fsi
Tenga en cuenta que también puede utilizar System.Environment.GetCommandLineArgs()
para acceder a los mismos argumentos.
Referencia a directivas de F# interactivo
Las directivas #r
y #load
abordadas anteriormente solo están disponibles en F# interactivo. Hay varias directivas que solo están disponibles en F# interactivo:
Directiva | Descripción |
---|---|
#r "nuget:..." |
Hace referencia a un paquete de NuGet |
#r "extname:..." |
Hacer referencia a un paquete de la extensión extname (por ejemplo, paket ) |
#r "assembly-name.dll" |
Hace referencia a un ensamblado del disco |
#load "file-name.fsx" |
Lee un archivo de código fuente, lo compila y lo ejecuta. |
#help |
Muestra información sobre directivas o documentación disponibles para funciones específicas. |
#I |
Especifica una ruta de búsqueda de ensamblaje entre comillas. |
#quit |
Termina una sesión de F# Interactive. |
#time on o #time off |
Por sí solo, #time activa y desactiva la presentación de información sobre el rendimiento. Si el valor es on , F# interactivo mide el tiempo real, el tiempo de CPU y la información sobre recolección de elementos no utilizados que se interpreta y ejecuta. |
[^1]: Más información sobre las extensiones interactivas de F#.
Al especificar los archivos o rutas de acceso en F# Interactive, se espera un literal de cadena. Por tanto, los archivos y las rutas de acceso deben estar entre comillas y se aplicarán los caracteres de escape habituales. Puede usar el carácter @
para hacer que F# Interactive interprete una cadena que contenga una ruta de acceso como una cadena literal. Esto hace que F# Interactive pase por alto cualquier carácter de escape.
En otros casos, las comillas son opcionales, empezando por F# 9.
Directiva #help extendida
La directiva #help
ahora admite la visualización de documentación para funciones específicas. Puede pasar el nombre de la función directamente para recuperar los detalles.
#help List.map;;
La salida es como sigue:
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
Esta mejora facilita la exploración y comprensión de las bibliotecas de F# de forma interactiva.
Para obtener más información, consulte el devblog oficial.
Directivas de preprocesador compiladas e interactivas
Al compilar código en F# interactivo, tanto si se ejecuta de forma interactiva como si ejecuta un script, se define el símbolo INTERACTIVE. Al compilar código en el compilador, se define el símbolo COMPILED. Por consiguiente, si el código debe ser diferente en modo interactivo y en modo compilado, se pueden usar estas directivas de preprocesador de la compilación condicional para determinar cuál se va a usar. Por ejemplo:
#if INTERACTIVE
// Some code that executes only in FSI
// ...
#endif
Uso de F# interactivo en Visual Studio
Para ejecutar F# Interactive a través de Visual Studio, puede hacer clic en el botón F# Interactive de la barra de herramientas o presionar las teclas Ctrl+Alt+F. De este modo, se abrirá la ventana interactiva, que es una ventana de herramientas en la que se ejecuta una sesión de F# Interactive. También puede seleccionar el código que quiere ejecutar en la ventana interactiva y presionar la combinación de teclas Alt+ENTRAR. F# Interactive se inicia en la ventana de herramientas con la etiqueta F# Interactive. Cuando use esta combinación de teclas, asegúrese de que la ventana del editor tiene el foco.
Tanto si usa la consola como si usa Visual Studio, aparece un símbolo del sistema y el intérprete espera una entrada por parte del usuario. Puede escribir código tal y como lo haría en un archivo de código fuente. Para compilar y ejecutar el código, escriba dos signos de punto y coma (;;) para finalizar una o varias líneas de entrada.
F# Interactive intenta compilar el código y, si lo logra, lo ejecuta e imprime en pantalla la signatura de los tipos y valores que compiló. Si se producen errores, el intérprete imprime en pantalla los mensajes de error.
El código escrito en una misma sesión tiene acceso a cualquier construcción escrita anteriormente, de modo que es posible crear programas. Un búfer extenso de la ventana de herramientas permite copiar el código en un archivo si es necesario.
Cuando F# Interactive se ejecuta en Visual Studio, lo hace de manera independiente del proyecto, de modo que, por ejemplo, no se pueden usar en F# Interactive las construcciones definidas en el proyecto a menos que se copie el código de dichas funciones en la ventana interactiva.
Puede controlar los argumentos (opciones) de la línea de comandos de F# interactivo ajustando la configuración. En el menú Herramientas, seleccione Opciones... y, después, expanda Herramientas de F#. Las dos configuraciones que puede cambiar son las opciones de F# Interactive y la opción F# Interactive de 64 bits, que solo es relevante si ejecuta F# Interactive en un equipo de 64 bits. Este valor determina si desea ejecutar la versión de 64 bits dedicada de fsi.exe o fsianycpu.exe, que usa la arquitectura del equipo para determinar si debe ejecutarse como un proceso de 32 o 64 bits.
Artículos relacionados
Título | Descripción |
---|---|
Opciones de F# Interactive | Describe la sintaxis y las opciones de línea de comandos de F# interactivo, fsi.exe. |