简体   繁体   English

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

[英]F#, namespaces, modules, fs and fsx

I'm aware of other questions about modules and namespaces in F#, but they're not helping me right now. 我知道有关F#中的模块和命名空间的其他 问题 ,但他们现在没有帮助我。

I've got a project with 我有一个项目

Utilities.fs Utilities.fs

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

Functions.fs Functions.fs

namespace Company.Project.Namespace
open Utilities

module Functions = 
     //stuff here

And I'm trying to test them in an fsx: 而我正试图在fsx中测试它们:

#load "Utilities.fs"
#load "Functions.fs"

which gives me error FS0039: The namespace or module 'Utilities' is not defined when I try to send it to FSI with Alt-Enter . 这给了我error FS0039: The namespace or module 'Utilities' is not defined当我尝试使用Alt-Enter将其发送到FSI时, error FS0039: The namespace or module 'Utilities' is not defined

I've tried adding same namespace at the top of the script file, but it doesn't like that. 我已经尝试在脚本文件的顶部添加相同的命名空间,但它不喜欢这样。

What's weird is that the background compiler doesn't shout at me. 奇怪的是后台编译器没有对我大喊大叫。

This seems to work, but is it the right approch? 这似乎有效,但它是正确的approch?

#load "Utilities.fs"
open Company.Project.Namespace
#load "Functions.fs"

Is there a 'reference' FSharp project somewhere, which contains examples of how to integrate all this stuff: namespaces, modules, classes, script files, tests etc.? 在某个地方是否有一个'参考'FSharp项目,其中包含如何集成所有这些内容的示例:命名空间,模块,类,脚本文件,测试等?

I'm not an expert with FSI, but some experimentation suggests that namespaces are only supported by #load declarations (not via typical interactions - sending a namespace declaration group to VFSI via Alt-Enter does not work), and that different interactions contribute different 'instances'. 我不是FSI的专家,但是一些实验表明只有#load声明支持命名空间(不是通过典型的交互 - 通过Alt-Enter向VFSI发送命名空间声明组不起作用),并且不同的交互有所不同“实例”。 For example, with the code file 例如,使用代码文件

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()

if I #load it more than once I get eg 如果我#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

Note that it seems the FSI_0003.Foo.Bar shadowed the FSI_0002 version. 请注意,似乎FSI_0003.Foo.Bar隐藏了FSI_0002版本。

So I'm thinking the part of the F# spec that says 所以我在考虑F#规范的一部分

Within a namespace declaration group, the namespace itself is implicitly opened if any preceding namespace declaration groups or referenced assemblies contribute to this namespace, eg 在名称空间声明组中,如果任何前面的名称空间声明组或引用的程序集对此名称空间有贡献,则会隐式打开名称空间本身,例如

 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 

However this only opens the namespace as constituted by preceding namespace declaration groups. 但是,这仅打开由前面的名称空间声明组构成的名称空间。

Does not interact with FSI, given FSI's limited understanding of namespaces. 鉴于FSI对命名空间的理解有限,不与FSI交互。 Specifically, I expect that the 'second #load' from your example opens eg FSI_000N+1 's version of the namespace, whereas the prior code was in FSI_000N . 具体来说,我希望您的示例中的“第二个#load”打开,例如FSI_000N+1的命名空间版本,而之前的代码在FSI_000N Which maybe-explains why the explicit open interaction fixes it; 这可能解释了为什么明确的open互动会修复它; you bring the existing, unshadowed FSI_000N stuff up to the top level before trying to (implicitly) reference it later. 在尝试(隐式)稍后引用它之前,你将现有的,没有FSI_000N内容提升到顶层。

I'm relatively new at this too, but this is what works for me when I'm testing in an fsx file: 我在这方面也比较新,但是当我在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

followed by my code that uses these libraries. 然后是我使用这些库的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM