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

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

3 ответа

Решение

Вероятно, вы можете реализовать это с помощью.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...

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

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

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

Другие вопросы по тегам