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

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

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

коммунальные услуги.fs

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

функции.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.Бар затенен Версия 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 пространств имен. В частности, я ожидаю, что "вторая #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

затем мой код, который использует эти библиотеки.