F#, пространства имен, модули, fs и 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
,
Я пытался добавить то же пространство имен в верхней части файла скрипта, но это не нравится.
Что странно, так это то, что фоновый компилятор не кричит на меня.
Кажется, это работает, но это правильный подход?
#load "Utilities.fs"
open Company.Project.Namespace
#load "Functions.fs"
Есть ли где-нибудь "справочный" проект FSharp, который содержит примеры того, как интегрировать все эти вещи: пространства имен, модули, классы, файлы сценариев, тесты и т. Д.?
2 ответа
Я не эксперт 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#, которая говорит
Внутри группы объявлений пространства имен само пространство имен неявно открывается, если какие-либо предшествующие группы объявлений пространства имен или ссылочные сборки вносят вклад в это пространство имен, например
namespace MyCompany.MyLibrary module Values1 = let x = 1 namespace MyCompany.MyLibrary // Implicit open of MyCompany.MyLibrary bringing Values1 into scope module Values2 = let x = Values1.x
Однако это только открывает пространство имен, состоящее из предшествующих групп объявлений пространства имен.
Не взаимодействует с FSI, учитывая ограниченное понимание FSI пространств имен. В частности, я ожидаю, что в вашем примере откроется 'second #load', например: FSI_000N+1
версия пространства имен, тогда как предыдущий код FSI_000N
, Что может быть - объясняет, почему явное open
взаимодействие исправляет это; вы приносите существующее, не затененное FSI_000N
до верхнего уровня, прежде чем пытаться (неявно) ссылаться на него позже.
Я тоже относительно новичок в этом, но это то, что работает для меня, когда я тестирую в файле fsx:
#if INTERACTIVE
#r @"C:\Program Files\FSharpPowerPack-2.0.0.0\bin\FParsec.dll"
#r @"C:\Program Files\FSharpPowerPack-2.0.0.0\bin\FParsecCS.dll"
#endif
open FParsec.Primitives
open FParsec.CharParsers
затем мой код, который использует эти библиотеки.