Compartilhar via


Programação interativa com F#

F# Interactive (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 (Read, Evaluate, Print Loop) para F#.

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

Observação

Se pretender usar o F# interativo em tempo de execução do .NET Framework, vai precisar das ferramentas de compilação Visual Studio Build Tools ou de uma edição do Visual Studio instalada e executar o comando FsiAnyCPU.exe a partir de um "Prompt de Comando do Desenvolvedor" ou simplesmente disponibilizar FsiAnyCPU.exe na variável de ambiente PATH, na linha de comandos em vez de dotnet fsi.

As ferramentas suportam definir a versão do runtime do F# Interactive.

  • No Visual Studio: na barra de menus, Ferramentas / Opções depois Ferramentas F# / F# Interactivee ajuste a opção Utilizar o .NET Core Scripting.
  • No Visual Studio Code (extensão ionide): Na paleta de comandos, Preferências: Abrir Configurações do Usuárioe, em seguida, Extensões / F# / FSharp: Fsi Sdk File Path.

Para obter informações sobre opções de linha de comando disponíveis, consulte Opções interativas F#.

Executando código diretamente em F# Interactive

Como o F# Interactive é um REPL (ciclo de leitura-avaliação-impressão), podes executar código de forma interativa. Aqui está um exemplo de uma sessão interativa depois de executar dotnet fsi a partir 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ê notará duas coisas principais:

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

O F# Interactive também suporta entrada de várias linhas. Você só precisa encerrar seu envio com um ponto-e-vírgula duplo (;;). Considere o seguinte trecho que foi colado e avaliado pelo 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 = ()

>

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

Criação de scripts com F#

Avaliar o código interativamente no F# Interactive pode ser uma ótima ferramenta de aprendizado, mas você descobrirá rapidamente que não é tão produtivo quanto escrever código em um editor normal. Para suportar a 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 depois executar o assembly já compilado, pode-se simplesmente executar dotnet fsi e especificar o nome do ficheiro do script do código-fonte F#. O F# Interactive lê o código e executa-o 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 este arquivo é criado em sua máquina, 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# é suportado nativamente no Visual Studio e Visual Studio Code.

Referenciando pacotes em F# Interactive

Observação

Sistema de gestão de pacotes é extensível, consulte mais informações sobre os plugins e o mecanismo de extensão.

Desde a versão 5.0 da linguagem, o F# Interactive suporta referenciar pacotes através de um mecanismo de extensibilidade; diretamente, 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á utilizada a versão não experimental mais recente disponível. Para fazer referência a uma versão específica, introduza a versão através de uma vírgula. Isso pode ser útil ao fazer referência a uma versão preliminar de um pacote. Por exemplo, considere este script usando uma versão de visualização 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 origem de pacote

Você também pode especificar uma fonte de pacote com o comando #i. O exemplo a seguir especifica uma fonte remota e uma fonte 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 também levar em conta as fontes remotas e/ou locais adicionadas a um script.

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

Observação

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 Saturn, Giraffe, WinForms não estão disponíveis. Isso está sendo rastreado na edição #9417. WinForms, ainda funciona na versão .NET Framework do F# Interactive.

Para carregar extensões adicionais ao lado daquelas fornecidas 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).

Referenciando assemblies em disco com F# interativo

Como alternativa, se você tiver um assembly no disco e desejar fazer referência a ele 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

Uma vez compilado, você pode consultá-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 quiser num script.

Carregando outros scripts

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

Considere as seguintes Script1.fsx:

let square x = x * x

E o ficheiro 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.

Observação

É necessária a declaração open Script1. Isso ocorre porque as construções em um script F# são compiladas 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 minúsculo, como script3.fsx o nome do módulo implícito será automaticamente colocado em maiúsculas e você precisará usáopen Script3. Se desejar que um script carregável defina construções em um namespace específico de módulo, você pode 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 do F#. Ele permite que você personalize coisas 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, 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 da diretiva interativa F#

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

Diretiva Descrição
#r "nuget:..." Faz referência a um pacote do NuGet
#r "extname:..." Fazer referência a um pacote da extensão extname[^1] (como paket)
#r "assembly-name.dll" Faz referência a um assembly em 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 Encerra uma sessão interativa do F#.
#time on ou #time off Por si só, #time alterna se deseja exibir informações de desempenho. Quando é on, o F# Interactive mede informações em tempo real, tempo de CPU e coleta de lixo para cada seção do código que é interpretada e executada.

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

Quando se especificam arquivos ou caminhos no F# Interactive, é esperado um literal de cadeia de caracteres. 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 o F# Interactive interprete uma cadeia de caracteres que contém um caminho como uma cadeia de caracteres literal. Isso faz com que o F# Interactive ignore todos os caracteres de escape.

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

Diretiva expandida #help

A diretiva #help agora suporta a 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

Quando você compila código em F# Interactive, quer esteja executando interativamente ou executando um script, o símbolo INTERACTIVE é definido. Quando você compila código no compilador, o símbolo COMPILED é definido. Assim, se o código precisa ser diferente nos modos compilado e interativo, você pode 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# Interactive através do Visual Studio, você pode clicar no botão apropriado da barra de ferramentas rotulado F# Interactiveou usar as teclas Ctrl+Alt+F. Isso abrirá a janela interativa, uma janela de ferramenta que executa uma sessão interativa do F#. Você também pode selecionar algum código que deseja executar na janela interativa e pressionar a combinação de teclas Alt+Enter. F# Interactive começa em uma janela de ferramenta rotulada F# Interactive. Quando utilizar esta combinação de teclas, certifique-se de que 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 intérprete aguardará 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.

O F# Interactive tenta compilar o código e, se for bem-sucedido, executa o código e imprime a assinatura dos tipos e valores que compilou. Se ocorrerem erros, o intérprete imprime as mensagens de erro.

O código inserido na mesma sessão tem acesso a todas as construções inseridas anteriormente, para que você possa criar programas. Um buffer extenso na janela da ferramenta permite que você copie o código em um arquivo, se necessário.

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

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

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