Я знаю другоео вопросы о модулях и пространствах имен в 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"
Есть ли где-нибудь 'ссылочный' проект Фа-диеза, который содержит примеры того, как интегрировать весь этот материал: пространства имен, модули, классы, файлы сценария, тестируют и т.д.?
Я не эксперт в 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
материал на верхний уровень, прежде чем пытаться (неявно) ссылаться на него позже.