如何在嵌套作用域中引用同名的类型

Asi*_*sik 3 f#

我正在尝试访问上层模块中定义的类型:

module MainModule

type Data = { stuff }

module XmlDeserialization =
    type Data() =
       [<XmlAttribute("stuff")>]
       member val stuff ...

       member x.ToDomainType() =
           {
               stuff = x.stuff
           } : MainModule.Data
Run Code Online (Sandbox Code Playgroud)

问题是,最后一行没有编译,因为"未定义类型'MainModule'."

我能够使用命名空间来实现我想要的,但是可以使用模块来实现吗?

Fyo*_*kin 5

您无法MainModuleMainModule自身体内引用,因为此时,模块在技术上尚未定义.这可以用较小的程序重现:

module M =

  type T = T
  let x: T = T    // OK
  let y: M.T = T  // Error: module M is not defined yet
Run Code Online (Sandbox Code Playgroud)

最简单的解决方案是MainModule在开始定义之前完成定义XmlDeserialization:

module MainModule =

    type Data = { stuff }

module XmlDeserialization =
    type Data() =
       [<XmlAttribute("stuff")>]
       member val stuff ...

       member x.ToDomainType() =
           {
               stuff = x.stuff
           } : MainModule.Data  // Works now
Run Code Online (Sandbox Code Playgroud)

但是如果你坚持XmlDeserialization要嵌套MainModule,并且你坚持认为这些类型必须具有相同的名称,那么你可以在定义阴影之前通过创建原始类型的别名来解决类型阴影:

module XmlDeserialization =

    // Alias the original type
    type MainModule_Data = Data

    type Data() =
       [<XmlAttribute("stuff")>]
       member val stuff ...

       member x.ToDomainType() =
           {
               stuff = x.stuff
           } : MainModule_Data  // Refer by alias: works now
Run Code Online (Sandbox Code Playgroud)