Compartilhar via


Programação interativa com F#

F# Interativo (dotnet fsi) é usado para executar código F# interativamente no console ou para executar scripts F#. Em outras palavras, o F# Interativo executa um REPL (loop de leitura, avaliação e impressão) para a linguagem F#.

Para executar o F# Interativo no console, execute dotnet fsi. Você encontrará dotnet fsi em qualquer SDK do .NET.

Nota

Se você pretende usar o F# interativo no runtime do .NET Framework, precisará do do Visual Studio Build Tools ou de uma edição do Visual Studio instalado e invocará o comando FsiAnyCPU.exe de um "Prompt de Comando do Desenvolvedor" ou simplesmente disponibilizará FsiAnyCPU.exe na variável de ambiente PATH, no lugar da linha de comando dotnet fsi.

As ferramentas dão suporte à definição do runtime interativo da versão F#:

  • No Visual Studio: na barra de menus, Ferramentas / OpçõesFerramentas F# / F# Interactive e ajustar Utilizar Scripts do .NET Core.
  • No Visual Studio Code (extensão Ionide): na Paleta de Comandos, Preferências: Abrir Configurações do Usuário, em seguida, Extensões / F# / FSharp: Caminho do Arquivo Fsi Sdk.

Para saber mais sobre as opções da linha de comando disponíveis, veja Opções de F# Interativo.

Executando código diretamente no F# Interativo

Como o F# Interactive é um REPL (read-eval-print loop), você pode executar código nele interativamente. Aqui está um exemplo de uma sessão interativa depois de executar dotnet fsi da linha de 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 = ()

Você observará duas coisas principais:

  1. Todo o código deve ser encerrado com um ponto-e-vírgula duplo (;;) para ser avaliado
  2. O código é avaliado e armazenado em um valor it. Você pode referenciar it interativamente.

O F# Interativo também dá suporte à entrada de várias linhas. Você só precisa terminar seu envio com um ponto-e-vírgula duplo (;;). Considere o seguinte snippet que foi colado e avaliado pelo F# Interativo:

> 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 = ()

>

A formatação do código é preservada e há um ponto-e-vírgula duplo (;;) encerrando a entrada. F# Interativo, em seguida, avaliou o código e imprimiu os resultados!

Script com F#

Avaliar o código interativamente no F# Interativo pode ser uma ótima ferramenta de aprendizado, mas você descobrirá rapidamente que ele não é tão produtivo quanto escrever código em um editor normal. Para dar suporte à edição de código normal, você pode escrever scripts F#.

Os scripts usam a extensão de arquivo .fsx. Em vez de compilar o código-fonte e executar o assembly compilado em seguida, basta executar dotnet fsi e especificar o nome do arquivo do script do código-fonte em F# e o F# interativo lê o código e o executa em tempo real. Por exemplo, considere o seguinte script chamado 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 esse arquivo é criado em seu computador, você pode executá-lo com dotnet fsi e ver a saída diretamente na janela do terminal:

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

O script F# tem suporte nativo em do Visual Studio e do Visual Studio Code.

Referenciando pacotes no F# Interativo

Nota

O sistema de gerenciamento de pacotes é extensível, consulte mais sobre os plug-ins de e o mecanismo de extensão.

Desde a versão 5.0 da linguagem, o F# Interativo dá suporte a pacotes de referência por meio de um mecanismo de extensibilidade; de forma integrada, ele pode referenciar pacotes NuGet com a sintaxe #r "nuget:" e uma versão opcional:

#r "nuget: Newtonsoft.Json"
open Newtonsoft.Json

let data = {| Name = "Don Syme"; Occupation = "F# Creator" |}
JsonConvert.SerializeObject(data)

Se uma versão não for especificada, será usado o pacote mais recente disponível que não esteja em versão prévia. Para fazer referência a uma versão específica, introduza a versão por meio de uma vírgula. Isso pode ser útil ao referenciar uma versão prévia de um pacote. Por exemplo, considere esse script usando uma versão prévia do 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)}"

Especificando uma fonte de pacote

Você também pode especificar uma fonte de pacote com o comando #i. O exemplo a seguir especifica uma origem remota e local:

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

Isso instruirá o mecanismo de resolução nos bastidores a levar em conta também as fontes remotas e/ou locais adicionadas ao script.

Você pode especificar quantas referências de pacote desejar em um script.

Nota

Atualmente, há uma limitação para scripts que usam referências de estrutura (por exemplo,Microsoft.NET.Sdk.Web ou Microsoft.NET.Sdk.WindowsDesktop). Pacotes como Saturno, Girafa, WinForms não estão disponíveis. Isso está sendo acompanhado no problema n° 9417. WinForms, ainda funciona na versão do .NET Framework do F# Interactive.

Para carregar extensões adicionais ao lado daquelas enviadas com o SDK e/ou com suas ferramentas, use o sinalizador --compilertool:<extensionsfolderpath> como argumento para a sessão interativa F# (ou nas configurações de ferramentas).

Referência a assemblies em disco com o F# Interativo

Como alternativa, se você tiver um assembly no disco e desejar referenciá-lo em um script, poderá usar a sintaxe #r para especificar um assembly. Considere o seguinte código em um projeto compilado em MyAssembly.dll:

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

Depois de compilado, você pode referenciá-lo em um arquivo chamado Script.fsx assim:

#r "path/to/MyAssembly.dll"

printfn $"{MyAssembly.myFunction 10 40}"

A saída é a seguinte:

dotnet fsi Script.fsx
90

Você pode especificar quantas referências de assemblies desejar em um script.

Carregando outros scripts

Ao criar scripts, muitas vezes pode ser útil usar scripts diferentes para tarefas diferentes. Às vezes, talvez você queira reutilizar o código de um script em outro. Em vez de copiar o conteúdo no arquivo, basta carregá-lo e avaliá-lo com #load.

Considere o seguinte Script1.fsx:

let square x = x * x

Considere também o arquivo de consumo Script2.fsx:

#load "Script1.fsx"
open Script1

printfn $"%d{square 12}"

Você pode avaliar Script2.fsx assim:

dotnet fsi Script2.fsx
144

Você pode especificar quantas diretivas #load quiser em um script.

Nota

A declaração open Script1 é necessária. Isso ocorre porque os constructos em um script F# são compilados em um módulo de nível superior que é o nome do arquivo de script em que ele está. Se o arquivo de script tiver um nome em letras minúsculas, como script3.fsx, o nome do módulo implícito será automaticamente capitalizado e você precisará usar open Script3. Se você quiser que um script carregável defina constructos em um namespace específico do módulo, você poderá incluir um namespace de declaração de módulo, por exemplo:

module MyScriptLibrary

Usando o objeto fsi no código F#

Os scripts F# têm acesso a um objeto fsi personalizado que representa a sessão interativa F#. Ele permite personalizar itens como formatação de saída. É também como você pode acessar argumentos de linha de comando.

O exemplo a seguir mostra como obter e usar argumentos de linha de comando:

let args = fsi.CommandLineArgs

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

Quando avaliado, ele imprime todos os argumentos. O primeiro argumento é sempre o nome do script que é avaliado:

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

Você também pode usar System.Environment.GetCommandLineArgs() para acessar os mesmos argumentos.

Referência de diretiva do F# Interativo

As diretivas de #r e #load vistas anteriormente só estão disponíveis no F# Interativo. Há várias diretivas disponíveis apenas no F# Interativo:

Diretiva Descrição
#r "nuget:..." Faz referência a um pacote do NuGet
#r "extname:..." Referenciar um pacote de extensão extname [^1] (como paket)
#r "assembly-name.dll" Faz referência a um assembly no disco
#load "file-name.fsx" Lê um arquivo de origem, compila-o e executa-o.
#help Exibe informações sobre diretivas ou documentação disponíveis para funções específicas.
#I Especifica um caminho de pesquisa de assembly entre aspas.
#quit Finaliza uma sessão do F# interativo.
#time on ou #time off Por si só, #time alterna se as informações de desempenho devem ser exibidas. Quando é on, o F# Interactive mede informações de tempo real, tempo de CPU e coleta de lixo para cada seção de código que é interpretada e executada.

[^1]: mais sobre extensões interativas de F#.

Quando você especificar arquivos ou caminhos em F# interativo, uma sequência literal é esperada. Portanto, arquivos e caminhos devem estar entre aspas e os caracteres de escape usuais se aplicam. Você pode usar o caractere @ para fazer com que F# Interactive interprete uma cadeia de caracteres que contém um caminho como uma string literal. Isso faz com que o F# Interativo ignore todos os caracteres de escape.

Para outros casos, as aspas são opcionais, começando com F# 9.

Diretiva #help estendida

A diretiva #help agora dá suporte à exibição de documentação para funções específicas. Você pode passar o nome da função diretamente para recuperar detalhes.

#help List.map;;

A saída é a seguinte:

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

Esse aprimoramento facilita a exploração e a compreensão interativa das bibliotecas F#.

Para obter mais detalhes, consulte o devblog oficial .

Diretivas de pré-processador interativas e compiladas

O símbolo INTERATIVO será definido ao compilar códigos no F# Interativo tanto para execuções interativas quanto para execução de um script. Quando você compila o código no compilador, o símbolo COMPILADO é definido. Portanto, se o código precisar ser diferente em modos compilados e interativos, você poderá usar essas diretivas de pré-processador para compilação condicional para determinar qual usar. Por exemplo:

#if INTERACTIVE
// Some code that executes only in FSI
// ...
#endif

Usando f# interativo no Visual Studio

Para executar o F# Interativo por meio do Visual Studio, você pode clicar no botão de barra de ferramentas apropriado rotulado F# Interactiveou usar as teclas Ctrl+Alt+F. Isso abrirá a janela interativa, uma janela de ferramentas que roda uma sessão do F# Interactive. Você também pode selecionar algum código que deseja executar na janela interativa e acertar a combinação de teclas Alt+Enter. O F# Interativo começa em uma janela de ferramentas rotulada F# Interactive. Ao usar essa combinação de teclas, verifique se a janela do editor tem o foco.

Se você estiver usando o console ou o Visual Studio, um prompt de comando será exibido e o interpretador aguarda sua entrada. Você pode inserir o código da mesma forma que faria em um arquivo de código. Para compilar e executar o código, insira dois ponto-e-vírgula (;;) para encerrar uma linha ou várias linhas de entrada.

F# Interativo tenta compilar o código e, se bem-sucedido, executa o código e imprime a assinatura dos tipos e valores que ele compilou. Se ocorrerem erros, o interpretador imprimirá as mensagens de erro.

O código inserido na mesma sessão tem acesso a quaisquer constructos inseridos anteriormente, para que você possa criar programas. Um buffer extenso na janela de ferramentas permite copiar o código para um arquivo, se necessário.

Quando executado no Visual Studio, o F# Interativo é executado independentemente do seu projeto, portanto, por exemplo, você não pode usar constructos definidos em seu projeto no F# Interativo, a menos que você copie o código da função para a janela interativa.

Você pode controlar os argumentos de linha de comando interativos do F# (opções) ajustando as configurações. No menu Ferramentas, selecione Opções... e expanda Ferramentas do F#. As duas configurações que podem ser alteradas são as opções do F# interativo e a configuração do F# Interativo de 64 bits, que é relevante apenas se você estiver executando o F# interativo em uma máquina de 64 bits. Essa configuração determina se você deseja executar a versão dedicada de 64 bits de fsi.exe ou fsianycpu.exe, que usa a arquitetura do computador para determinar se deve ser executada como um processo de 32 bits ou 64 bits.

Título Descrição
opções interativas F# Descreve a sintaxe da linha de comando e as opções do F# Interativo, fsi.exe.