F#,名称空间,模块,fs和fsx

Ben*_*jol 27 f# namespaces module projects-and-solutions f#-interactive

我知道有关F#中的模块和命名空间的其他 问题,但他们现在没有帮助我.

我有一个项目

Utilities.fs

namespace Company.Project.Namespace
module Utilities = 
     //stuff here
Run Code Online (Sandbox Code Playgroud)

Functions.fs

namespace Company.Project.Namespace
open Utilities

module Functions = 
     //stuff here
Run Code Online (Sandbox Code Playgroud)

而我正试图在fsx中测试它们:

#load "Utilities.fs"
#load "Functions.fs"
Run Code Online (Sandbox Code Playgroud)

error FS0039: The namespace or module 'Utilities' is not defined当我尝试将它发送到FSI时,它给了我Alt-Enter.

我已经尝试在脚本文件的顶部添加相同的命名空间,但它不喜欢这样.

奇怪的是后台编译器没有对我大喊大叫.

这似乎有效,但它是正确的approch?

#load "Utilities.fs"
open Company.Project.Namespace
#load "Functions.fs"
Run Code Online (Sandbox Code Playgroud)

在某个地方是否有一个'参考'FSharp项目,其中包含如何集成所有这些内容的示例:命名空间,模块,类,脚本文件,测试等?

Bri*_*ian 9

我不是FSI的专家,但是一些实验表明名称空间只有#load声明支持(不是通过典型的交互 - 通过Alt-Enter向VFSI发送名称空间声明组不起作用),并且不同的交互会产生不同的'实例".例如,使用代码文件

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()
Run Code Online (Sandbox Code Playgroud)

如果我#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
Run Code Online (Sandbox Code Playgroud)

请注意,似乎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
Run Code Online (Sandbox Code Playgroud)

但是,这仅打开由前面的名称空间声明组构成的名称空间.

鉴于FSI对命名空间的理解有限,不与FSI交互.具体来说,我希望你的例子中的'second #load'打开例如FSI_000N+1命名空间的版本,而先前的代码是FSI_000N.这可能解释了为什么显式open交互修复了它; FSI_000N在尝试(隐式)稍后引用它之前,你将现有的,没有遮盖的东西带到顶层.

  • 是的,当它发生时,我的问题是我的实际代码的一个淡化的例子.我最终通过在每个#load之间重新打开命名空间来实现它... (3认同)

Dav*_*ite 8

我在这方面也比较新,但是当我在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
Run Code Online (Sandbox Code Playgroud)

然后是我使用这些库的代码.