F#, пространства имен, модули, фс и fsx

Я знаю другоео вопросы о модулях и пространствах имен в F#, но они не помогают мне прямо сейчас.

У меня есть проект с

Utilities.fs

namespace Company.Project.Namespace
module Utilities = 
     //stuff here

Functions.fs

namespace Company.Project.Namespace
open Utilities

module Functions = 
     //stuff here

И я пытаюсь протестировать их в fsx:

#load "Utilities.fs"
#load "Functions.fs"

который дает мне error FS0039: The namespace or module 'Utilities' is not defined когда я пытаюсь отправить его в FSI с Alt-Enter.

Я попытался добавить то же пространство имен наверху файла сценария, но этому не нравится это.

То, что является странным, - то, что фоновый компилятор не кричит на меня.

Это, кажется, работает, но действительно ли это - право approch?

#load "Utilities.fs"
open Company.Project.Namespace
#load "Functions.fs"

Есть ли где-нибудь 'ссылочный' проект Фа-диеза, который содержит примеры того, как интегрировать весь этот материал: пространства имен, модули, классы, файлы сценария, тестируют и т.д.?

27
задан Community 23 May 2017 в 10:30
поделиться

1 ответ

Я не эксперт в FSI, но некоторые эксперименты показывают, что пространства имен поддерживаются только объявлениями #load (не через типичные взаимодействия - отправка группы объявлений пространств имен в VFSI через Alt-Enter не работает), и что разные взаимодействия вносят разные "экземпляры". Например, с файлом кода

namespace Foo

type Bar() =
    member this.Qux() = printfn "hi"

namespace Other

type Whatever() = class end

namespace Foo

module M =
    let bar = new Bar()
    bar.Qux()

если я #load его более одного раза, я получаю, например,

> [Loading C:\Program.fs]
hi

namespace FSI_0002.Foo
  type Bar =
    class
      new : unit -> Bar
      member Qux : unit -> unit
    end
namespace FSI_0002.Other
  type Whatever =
    class
      new : unit -> Whatever
    end
namespace FSI_0002.Foo
  val bar : Bar

> #load @"C:\Program.fs";;
> [Loading C:\Program.fs]
hi

namespace FSI_0003.Foo
  type Bar =
    class
      new : unit -> Bar
      member Qux : unit -> unit
    end
namespace FSI_0003.Other
  type Whatever =
    class
      new : unit -> Whatever
    end
namespace FSI_0003.Foo
  val bar : Bar

> new Foo.Bar();;
> val it : Foo.Bar = FSI_0003.Foo.Bar

Обратите внимание, что, похоже, FSI_0003.Foo.Bar затеняет версию FSI_0002.

Поэтому я думаю, что часть спецификации F#, в которой говорится

В группе объявления пространства имен, само пространство имен неявно открыто, если любые предшествующие группы объявления пространства имен или ссылающиеся сборки вносят вклад в это пространство имен, например,

пространство имен MyCompany.MyLibrary 

 модуль Values1 = 
 пусть x = 1

пространство имен MyCompany.MyLibrary 

 // Неявное открытие MyCompany.MyLibrary приводит Values1 в область видимости

 модуль Values2 = 
 let x = Values1.x

Однако это открывает только пространство имен как это определено предшествующими группами пространства имен группы объявлений.

Не взаимодействует с FSI, учитывая ограниченное понимание FSI пространств имен. В частности, я ожидаю, что "вторая #load" из вашего примера открывает, например, версию пространства имен FSI_000N+1, тогда как предыдущий код был в FSI_000N. Что, возможно, объясняет, почему явное взаимодействие open исправляет ситуацию; вы поднимаете существующий, незатененный FSI_000N материал на верхний уровень, прежде чем пытаться (неявно) ссылаться на него позже.

9
ответ дан 28 November 2019 в 05:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: