F # interactive - как увидеть все переменные, определенные в текущем сеансе

В F # interactive, как я могу увидеть список переменных/функций, определенных в этом сеансе? Как функция whos() в python или ls() в R? Спасибо.

Ответ 1

Вы можете реализовать это с помощью .NET Reflection. Локальные переменные и функции определяются как статические свойства/методы типов в одной динамической сборке. Вы можете получить эту сборку, вызвав GetExecutingAssembly (в самом FSI), а затем просмотрите типы, чтобы найти все подходящие свойства.

Ниже приведена разумно работающая функция для получения локальных переменных:

open System.Reflection
open System.Collections.Generic

let getVariables() = 
  let types = Assembly.GetExecutingAssembly().GetTypes()
  [ for t in types |> Seq.sortBy (fun t -> t.Name) do
      if t.Name.StartsWith("FSI_") then 
        let flags = BindingFlags.Static ||| BindingFlags.NonPublic |||
                    BindingFlags.Public
        for m in t.GetProperties(flags) do 
          yield m.Name, lazy m.GetValue(null, [||]) ] |> dict

Вот пример:

> let test1 = "Hello world";;
val test1 : string = "Hello world"

> let test2 = 42;;
val test2 : int = 42

> let vars = getVariables();;
val vars : System.Collections.Generic.IDictionary<string,Lazy<obj>>

> vars.["test1"].Value;;
val it : obj = "Hello world"

> vars.["test2"].Value;;
val it : obj = 42

Функция возвращает "ленивое" значение назад (потому что это был самый простой способ записать его без предварительного считывания значений всех переменных, что было бы медленным), поэтому вам нужно использовать свойство Value. Также обратите внимание, что вы получаете object назад - потому что система типа F # не знает тип - вам придется использовать ее динамически. Вы можете получить все имена, просто итерации по vars...

Ответ 2

Я разрабатываю FsEye, в котором используется модифицированная версия метода @Tomas (отфильтровывает единицы измерения и функции, ценные вары и только берет последний it var), чтобы захватить все переменные сеанса FSI при каждом представлении и визуально отображает их в дереве, чтобы вы могли развернуть их графические объекты.

Вы можете увидеть мою измененную версию здесь.

Ответ 3

К сожалению, на этом этапе в FSI нет способа сделать это.