Compartir a través de


Programación interactiva con F#

F# Interactive (dotnet fsi) se usa para ejecutar código de F# de forma 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 de código directamente en F# Interactivo

Dado que F# Interactive es un REPL (bucle read-eval-print), puede ejecutar código de forma interactiva en él. 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 cosas principales:

  1. Todo el código debe terminar con un punto y coma doble (;;) para ser evaluado.
  2. El código se evalúa y almacena en un valor de it. Puede hacer referencia a it de forma interactiva.

F# Interactive también admite entradas de varias líneas. Solo tiene que finalizar el envío con un punto y coma doble (;;). Tenga en cuenta el siguiente fragmento de código que se ha pegado y evaluado por 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 = ()

>

El formato del código se conserva y hay un punto y coma doble (;;) que termina la entrada. F# Interactivo después evaluó el código e imprimió los resultados.

Scripting con F#

Evaluar el código de forma interactiva en F# Interactive puede ser una excelente herramienta de aprendizaje, pero rápidamente descubrirá que no es tan productivo como escribir código en un editor normal. Para admitir la edición de código normal, 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 del código fuente de F# y F# interactivo lee el código y lo ejecuta en tiempo real. Por ejemplo, considere el siguiente script denominado 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 se crea este archivo en la máquina, puede ejecutarlo con dotnet fsi y ver la salida directamente en la ventana del terminal:

dotnet fsi Script.fsx
[1; 9; 25; 49; 81]

El scripting de F# se admite de forma nativa en Visual Studio y Visual Studio Code.

Hacer referencia a paquetes en F# Interactive

Nota

El sistema de administración de paquetes es extensible, consulte más sobre los complementos de y el mecanismo de extensión.

Desde la versión 5.0 del lenguaje, F# Interactive admite la referencia de paquetes a través de un mecanismo de extensibilidad; De fábrica, 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 una versión, se toma el paquete sin versión preliminar más alto disponible. Para hacer referencia a una versión específica, introduzca la versión a través de una coma. Esto puede resultar útil al hacer 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 de un origen de paquete

También puede especificar un origen de paquete con el comando #i. En el ejemplo siguiente se especifica un origen remoto y local:

#i "nuget: https://my-remote-package-source/index.json"
#i """nuget: C:\path\to\my\local\source"""

Esto indicará al motor de resolución en segundo plano que también tenga en cuenta los orígenes remotos o locales 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, WinForms no están disponibles. Se está realizando un seguimiento en la incidencia 9417. WinForms, todavía funciona en la versión de .NET Framework de F# Interactive.

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 interactiva de F# (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 eso en un script, puede usar la sintaxis de #r para especificar un ensamblado. Tenga en cuenta el código siguiente de un proyecto compilado en MyAssembly.dll:

// MyAssembly.fs
module MyAssembly
let myFunction x y = x + 2 * y

Una vez compilado, puede hacer referencia a él en un archivo denominado Script.fsx así:

#r "path/to/MyAssembly.dll"

printfn $"{MyAssembly.myFunction 10 40}"

La salida es la siguiente:

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 resultar útil usar scripts diferentes para diferentes tareas. A veces, es posible que quiera reutilizar el código de un script en otro. 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 la siguiente manera:

dotnet fsi Script2.fsx
144

Puede especificar tantas directivas de #load como quiera 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 que es el nombre del archivo de script en el que se encuentra. Si el archivo de script tiene un nombre en minúsculas, como script3.fsx, el nombre del módulo implícito se escribe automáticamente en mayúsculas y deberá usar 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 código F#

Los scripts de F# tienen acceso a un objeto de fsi personalizado que representa la sesión interactiva de F#. Permite personalizar elementos como el formato de salida. También es cómo puede acceder a los argumentos de la línea de comandos.

En el ejemplo siguiente se muestra cómo obtener y usar argumentos de línea de comandos:

let args = fsi.CommandLineArgs

for arg in args do
    printfn $"{arg}"

Cuando se evalúa, imprime todos los argumentos. El primer argumento es siempre el nombre del script que se evalúa:

dotnet fsi Script1.fsx hello world from fsi
Script1.fsx
hello
world
from
fsi

También puede usar System.Environment.GetCommandLineArgs() para acceder a los mismos argumentos.

Referencia a directivas de F# interactivo

Las directivas #r y #load que se han visto anteriormente solo están disponibles en F# Interactive. Solo hay varias directivas disponibles en F# Interactive:

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 en el disco
#load "file-name.fsx" Lee un archivo de origen, 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 lo tanto, los archivos y las rutas de acceso deben estar entre comillas y se aplican 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 omita los caracteres 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 la siguiente:

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 oficial devblog.

Directivas de preprocesador interactivas y compiladas

Al compilar código en F# Interactive, tanto si se ejecuta de forma interactiva como si se ejecuta un script, se define el símbolo INTERACTIVE. Al compilar código en el compilador, se define el símbolo COMPILED. Por lo tanto, si el código debe ser diferente en modos compilados e interactivos, puede usar estas directivas de preprocesador para la compilación condicional para determinar qué 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. Al hacerlo, se abrirá la ventana interactiva, una ventana de herramientas que ejecuta una sesión interactiva de F#. También puede seleccionar código que quiera ejecutar en la ventana interactiva y presionar la combinación de teclas Alt+Entrar. F# Interactive se inicia en una ventana de herramientas etiquetada F# Interactive. Al usar esta combinación de teclas, asegúrese de que la ventana del editor tenga 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 como lo haría en un archivo de código. Para compilar y ejecutar el código, escriba dos punto y coma (;;) para finalizar una línea o varias líneas de entrada.

F# Interactive intenta compilar el código y, si se ejecuta correctamente, ejecuta el código e imprime la firma de los tipos y valores que compiló. Si se producen errores, el intérprete imprime los mensajes de error.

El código escrito en la misma sesión tiene acceso a las construcciones especificadas anteriormente, por lo que puede crear programas. Un búfer extenso en la ventana de herramientas le permite copiar el código en un archivo si es necesario.

Cuando se ejecuta en Visual Studio, F# Interactive se ejecuta independientemente del proyecto, por lo que, por ejemplo, no puede usar construcciones definidas en el proyecto en F# Interactive a menos que copie el código de la función en la ventana interactiva.

Puede controlar los argumentos de línea de comandos (opciones) interactivos de F# 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. Esta configuración determina si desea ejecutar la versión dedicada de 64 bits de fsi.exe o fsianycpu.exe, que usa la arquitectura de la máquina para determinar si se ejecuta como un proceso de 32 o 64 bits.

Título Descripción
Opciones de F# Interactive Describe la sintaxis y las opciones de la línea de comandos para F# Interactive, fsi.exe.