为啥 %A 文本格式不适用于 F# 中的内部模块?

Posted

技术标签:

【中文标题】为啥 %A 文本格式不适用于 F# 中的内部模块?【英文标题】:Why doesn't %A text formatting work with internal modules in F#?为什么 %A 文本格式不适用于 F# 中的内部模块? 【发布时间】:2018-02-06 22:39:15 【问题描述】:

以下代码未按预期格式化字符串(它只是打印完全限定的类名):

module internal MyModule.Types

type Action =
    | Add of int
    | Update of int * string
    | Delete of string

module internal MyModule.Print

open MyModule.Types

let printStuff (x:Action) =
    printfn "%A" x

但是,如果 MyModule.Types 未指定为 internal,则格式将按预期工作。为什么格式化不适用于internal 模块?跟反射有关系吗?除了将模块公开之外,还有其他解决方法吗?

我应该提到模块位于单独的 .fs 文件中。

【问题讨论】:

【参考方案1】:

这对我有用,例如我得到输出:

λ .\SO180207.exe 添加 10 添加 5 添加 5 [||]

你可以看到Add 10被打印出来了。此外,当我访问内部模块时,值和printfn "%A" 语句都被执行了。

这是项目的结构:

MyModule.fs 文件:

module internal MyModule.Types 

type Action =
    | Add of int
    | Update of int * string
    | Delete of string

let x = Add 5
printfn "%A" x

Program.fs 文件:

module MyModule.Program
open MyModule.Types

[<EntryPoint>]
let main argv =
    let x = Add 10 
    printfn "%A" x // prints Add 10 
    printfn "%A" MyModule.Types.x // prints Add 5 twice
    printfn "%A" argv 
    0 // return an integer exit code

所以也许你可以提供更多 F# 版本的信息,以及你运行的环境。 override x.ToString() 也可以在您的类型中使用。

补充说明: 老实说,内部模块可能有一些东西,好像我覆盖了ToString(),内部模块显然不喜欢它,并以***Exception 终止。例如。这在没有 internal 修饰符的情况下有效:

module MyModule.Types 

type Action =
    | Add of int
    | Update of int * string
    | Delete of string
    override x.ToString() = sprintf "%A" (x,x)
let x = Add 5
printfn "%A" x
printfn "%A" (x.ToString()) |> ignore

λ .\SO180207.exe 添加 10 添加 5 “(加 5,加 5)” 添加 5 [||]

【讨论】:

我编辑了问题以更准确地反映我正在运行的实际代码。代码在 .NET Framework 4.6.1 上运行 F# 4.4.1.0。 @Ralphie 类似的设置,但从您的描述看来,printfn 在设置内部修饰符时使用"%O" 而不是"%A"。不太清楚为什么会这样。

以上是关于为啥 %A 文本格式不适用于 F# 中的内部模块?的主要内容,如果未能解决你的问题,请参考以下文章

为啥调度和请求库不适用于 Python 中的此类?

为啥等待不适用于节点请求模块?

为啥 Intl.NumberFormat 不适用于 Safari 和 Firefox 中的单位?

为啥 JQuery keydown 适用于窗口而不适用于文本框?

为啥简化的 CommonJS Wrapper 语法不适用于我的 Dojo AMD 模块?

触摸事件是不是不适用于 iPad Safari 中的文本输入元素?