F #, пространства имен, модули, fs и fsx - PullRequest
27 голосов
/ 01 марта 2010

Мне известны другие вопросы о модулях и пространствах имен в 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 ]

9 голосов
/ 01 марта 2010

Я не эксперт в 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 получу его более одного раза, например

* +1007 *

Обратите внимание, что кажется, что 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 пространств имен. В частности, я ожидаю, что откроется «вторая #load» из вашего примера, например, Версия пространства имен FSI_000N+1, тогда как предыдущий код был FSI_000N. Что, возможно, объясняет, почему явное взаимодействие open исправляет это; Вы переносите существующий неотмеченный материал FSI_000N на верхний уровень, прежде чем пытаться (неявно) ссылаться на него позже.

8 голосов
/ 16 января 2011

Я тоже относительно новичок в этом, но это то, что мне подходит, когда я тестирую в файле 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

и мой код, использующий эти библиотеки.

...