Интерактивное программирование с помощью F#
F# Interactive (dotnet fsi) используется для интерактивного запуска кода F# в консоли или для выполнения скриптов F#. Другими словами, F# interactive выполняет REPL (Read, Evaluate, Print Loop) для F#.
Чтобы запустить F# Interactive из консоли, выполните dotnet fsi
. Вы найдете dotnet fsi
в любом пакете SDK для .NET.
Заметка
Если вы планируете использовать интерактивный F# в среде выполнения .NET Framework, вам потребуется средств сборки Visual Studio или установленной редакции Visual Studio, и вызвать команду FsiAnyCPU.exe
из командной строки "Командная строка разработчика", или просто сделать FsiAnyCPU.exe
доступной в переменной окружения PATH
вместо командной строки dotnet fsi
.
Инструменты поддерживают определение версии среды выполнения F# Interactive.
- В Visual Studio: в строке меню
средства средства F# F# и настройте использовать скриптов .NET Core. - В Visual Studio Code (расширение ionide): в палитре команд Настройки: откройте настройки пользователя, а затем Расширения / F# / FSharp: Путь к файлу SDK Fsi.
Сведения о доступных опциях командной строки см. в интерактивных опциях F#
Выполнение кода непосредственно в F# Interactive
Поскольку F# Interactive представляет собой REPL (цикл чтения-оценки-вывода), вы можете выполнять код интерактивно. Ниже приведен пример интерактивного сеанса после выполнения dotnet fsi
из командной строки:
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 = ()
Вы заметите две основные вещи:
- Весь код должен быть завершен с двойной точкой с запятой (
;;
) для вычисления - Код вычисляется и хранится в значении
it
. Вы можете ссылаться наit
интерактивно.
F# Interactive также поддерживает многострочный ввод. Вам просто нужно завершить отправку с двойной точкой с запятой (;;
). Рассмотрим следующий фрагмент кода, который был вставлен и оценен 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 = ()
>
Форматирование кода сохраняется и имеется двойная точка с запятой (;;
) с завершением входных данных. Затем F# Interactive оценил код и распечатал результаты!
Скриптирование с помощью F#
Интерактивное вычисление кода в F# Interactive может быть отличным средством обучения, но вы быстро обнаружите, что это не так продуктивно, как написание кода в обычном редакторе. Для поддержки обычного редактирования кода можно писать скрипты F#.
Скрипты используют расширение файла .fsx. Вместо компиляции исходного кода и последующего выполнения скомпилированной сборки можно просто запустить dotnet fsi и указать имя файла скрипта исходного кода F#, и F# интерактивный считывает код и выполняет его в режиме реального времени. Например, рассмотрим следующий скрипт с именем Script.fsx
:
let getOddSquares xs =
xs
|> List.filter (fun x -> x % 2 <> 0)
|> List.map (fun x -> x * x)
printfn "%A" (getOddSquares [1..10])
При создании этого файла на компьютере его можно запустить с помощью dotnet fsi
и просмотреть выходные данные непосредственно в окне терминала:
dotnet fsi Script.fsx
[1; 9; 25; 49; 81]
Скрипты F# изначально поддерживаются в Visual Studio и Visual Studio Code.
Ссылки на пакеты в F# Interactive
Заметка
Система управления пакетами расширяема, см. дополнительные сведения о подключаемых модулях и механизме расширения.
Начиная с выпуска 5.0 языка, F# Interactive поддерживает ссылки на пакеты через механизм расширяемости; по умолчанию, он может ссылаться на пакеты NuGet с помощью синтаксиса #r "nuget:"
и необязательной версии.
#r "nuget: Newtonsoft.Json"
open Newtonsoft.Json
let data = {| Name = "Don Syme"; Occupation = "F# Creator" |}
JsonConvert.SerializeObject(data)
Если версия не указана, принимается самый высокий доступный пакет, отличный от предварительной версии. Чтобы ссылаться на определенную версию, введите версию через запятую. Это может быть удобно при ссылке на предварительную версию пакета. Например, рассмотрим этот сценарий с помощью предварительной версии 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)}"
Указание источника пакета
Вы также можете указать источник пакета с помощью команды #i
. В следующем примере указывается удаленный и локальный источник:
#i "nuget: https://my-remote-package-source/index.json"
#i """nuget: C:\path\to\my\local\source"""
В этом случае подсистема разрешения будет также учитывать удаленные и (или) локальные источники, добавленные в скрипт.
Вы можете указать столько ссылок на пакеты, сколько вы хотите в скрипте.
Заметка
В настоящее время существует ограничение для сценариев, использующих ссылки на платформу (например,Microsoft.NET.Sdk.Web
или Microsoft.NET.Sdk.WindowsDesktop
). Пакеты, такие как Сатурн, Giraffe, WinForms недоступны. Это отслеживается в вопросах #9417.
WinForms по-прежнему работает в версии .NET Framework F# Interactive.
Чтобы загрузить дополнительные расширения рядом с пакетом SDK и (или) с помощью инструментов, используйте флаг --compilertool:<extensionsfolderpath>
в качестве аргумента для интерактивного сеанса F# (или в параметрах инструментов).
Ссылки на сборки на диске в F# Interactive
Кроме того, если у вас есть сборка на диске и хотите ссылаться на нее в скрипте, можно использовать синтаксис #r
для указания сборки. Рассмотрим следующий код в проекте, скомпилированном в MyAssembly.dll
:
// MyAssembly.fs
module MyAssembly
let myFunction x y = x + 2 * y
После компиляции вы можете ссылаться на него в файле с именем Script.fsx
, как показано:
#r "path/to/MyAssembly.dll"
printfn $"{MyAssembly.myFunction 10 40}"
Выходные данные приведены следующим образом:
dotnet fsi Script.fsx
90
Можно указать столько ссылок на сборки, сколько вы хотите в скрипте.
Загрузка других скриптов
При написании скриптов часто полезно использовать различные сценарии для различных задач. Иногда может потребоваться повторно использовать код из одного скрипта в другом. Вместо копирования его содержимого в файл можно просто загрузить и оценить его с помощью #load
.
Рассмотрим следующий Script1.fsx
:
let square x = x * x
Используемый для потребления файл, Script2.fsx
:
#load "Script1.fsx"
open Script1
printfn $"%d{square 12}"
Вы можете оценить Script2.fsx
так:
dotnet fsi Script2.fsx
144
Вы можете указать столько директив #load
, сколько вы хотите в скрипте.
Заметка
Декларация open Script1
обязательна. Это связано с тем, что конструкции в скрипте F# компилируются в модуль верхнего уровня, в который входит файл скрипта. Если файл скрипта имеет имя в нижнем регистре, например script3.fsx
, то подразумеваемое имя модуля автоматически пишется с заглавной буквы, и вам нужно будет использовать open Script3
. Если вы хотите, чтобы скрипт с возможностью загрузки определял конструкции в определенном пространстве имен модуля, можно включить пространство имен объявления модуля, например:
module MyScriptLibrary
Использование объекта fsi
в коде F#
Скрипты F# имеют доступ к пользовательскому объекту fsi
, представляющего интерактивный сеанс F#. Это позволяет настраивать такие вещи, как форматирование выходных данных. Кроме того, вы можете получить доступ к аргументам командной строки.
В следующем примере показано, как получить и использовать аргументы командной строки:
let args = fsi.CommandLineArgs
for arg in args do
printfn $"{arg}"
При вычислении он выводит все аргументы. Первым аргументом всегда является имя скрипта, который вычисляется:
dotnet fsi Script1.fsx hello world from fsi
Script1.fsx
hello
world
from
fsi
Вы также можете использовать System.Environment.GetCommandLineArgs()
для доступа к тем же аргументам.
Справочник по директивам для интерактивной среды F#
Ранее видимые директивы #r
и #load
доступны только в F# Interactive. Существует несколько директив, доступных только в F# Interactive:
Директива | Описание |
---|---|
#r "nuget:..." |
Ссылки на пакет из NuGet |
#r "extname:..." |
Ссылка на пакет из расширения extname [^1] (например, paket ) |
#r "assembly-name.dll" |
Ссылается на сборку на диске |
#load "file-name.fsx" |
Считывает исходный файл, компилирует его и запускает его. |
#help |
Отображает сведения о доступных директивах или документации для определенных функций. |
#I |
Определяет путь поиска сборки, заключённый в кавычки. |
#quit |
Завершает сеанс F# Interactive. |
#time on или #time off |
Сам по себе #time переключает режим отображения сведений о производительности. При on интерактивные меры F# в режиме реального времени, времени ЦП и сбор мусора для каждого раздела кода, интерпретированного и выполняемого. |
[^1]: Дополнительные сведения о интерактивных расширениях F#
При указании файлов или путей в F# Interactive ожидается строковый литерал. Поэтому файлы и пути должны находиться в кавычках, а обычные escape-символы применяются. Символ @
можно использовать, чтобы F# Interactive интерпретировал строку, содержащую путь, как буквальную строку. В результате F# Interactive игнорирует любые экранированные символы.
В других случаях кавычки являются необязательными, начиная с F# 9.
Расширенная директива #help
Директива #help
теперь поддерживает отображение документации для определенных функций. Вы можете передать имя функции непосредственно для получения сведений.
#help List.map;;
Выходные данные приведены следующим образом:
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
Это улучшение упрощает интерактивное изучение и понимание библиотек F#.
Дополнительные сведения см. в официальном блоге разработчиков .
Интерактивные и скомпилированные директивы препроцессора
При компиляции кода в F# Interactive, будь то интерактивное выполнение или выполнение скрипта, символ INTERACTIVE определяется. При компиляции кода в компиляторе символ COMPILED определяется. Таким образом, если код должен отличаться в скомпилированных и интерактивных режимах, можно использовать эти директивы препроцессора для условной компиляции, чтобы определить, какой из них следует использовать. Например:
#if INTERACTIVE
// Some code that executes only in FSI
// ...
#endif
Использование F# Interactive в Visual Studio
Чтобы запустить F# Interactive через Visual Studio, можно нажать соответствующую кнопку панели инструментов, помеченную интерактивнойF# или использовать клавиши CTRL+ALT+F. При этом откроется интерактивное окно, инструментальная панель, в которой выполняется интерактивный сеанс F#. Вы также можете выбрать код, который вы хотите запустить в интерактивном окне, и нажмите сочетание клавиш ALT+ВВОД. F# Interactive запускается в окне инструментов, помеченном F# Interactive. При использовании этого сочетания клавиш убедитесь, что в окне редактора есть фокус.
Независимо от того, используется ли консоль или Visual Studio, появится командная строка, и интерпретатор ожидает входных данных. Вы можете ввести код так же, как и в файле кода. Чтобы скомпилировать и выполнить код, введите две точки с запятой (;;) для завершения строки или нескольких строк входных данных.
F# Interactive пытается скомпилировать код и при успешном выполнении выполняет код и выводит подпись типов и значений, которые он скомпилировал. Если возникают ошибки, интерпретатор выводит сообщения об ошибках.
Код, введенный в том же сеансе, имеет доступ к любым введенным ранее конструкциям, поэтому вы можете создавать программы. Обширный буфер в окне инструментов позволяет при необходимости скопировать код в файл.
При запуске в Visual Studio F# Interactive выполняется независимо от вашего проекта, поэтому, например, вы не можете использовать конструкции, определенные в вашем проекте, в F# Interactive, если вы не скопируете код в интерактивное окно.
Вы можете управлять аргументами командной строки F# Interactive (параметрами), изменив параметры. В меню инструментов выберите параметры..., а затем разверните инструменты F#. Двумя параметрами, которые можно изменить, являются интерактивные параметры F# и параметр 64-разрядной интерактивной F#, который имеет значение только в том случае, если вы используете F# Interactive на 64-разрядном компьютере. Этот параметр определяет, следует ли запускать выделенную 64-разрядную версию fsi.exe или fsianycpu.exe, которая использует архитектуру компьютера для определения того, следует ли выполнять как 32-разрядный или 64-разрядный процесс.
Связанные статьи
Титул | Описание |
---|---|
интерактивные параметры F# | Описание синтаксиса командной строки и параметров для F# Interactive, fsi.exe. |