F#, namespaces, modules, fs and fsx

前端 未结 2 2110
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-16 10:13

I\'m aware of other questions about modules and namespaces in F#, but they\'re not helping me right now.

I\'ve got a project with

Utilities.fs

相关标签:
2条回答
  • 2020-12-16 10:34

    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'. 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 e.g.

    > [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.

    So I'm thinking the part of the F# spec that says

    Within a namespace declaration group, the namespace itself is implicitly opened if any preceding namespace declaration groups or referenced assemblies contribute to this namespace, e.g.

    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. Specifically, I expect that the 'second #load' from your example opens e.g. FSI_000N+1's version of the namespace, whereas the prior code was in FSI_000N. Which maybe-explains why the explicit open interaction fixes it; you bring the existing, unshadowed FSI_000N stuff up to the top level before trying to (implicitly) reference it later.

    0 讨论(0)
  • 2020-12-16 10:43

    I'm relatively new at this too, but this is what works for me when I'm testing in an fsx file:

    #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.

    0 讨论(0)
提交回复
热议问题