F#编译器需要项目引用,但方法是私有的

ban*_*low 10 methods f# compiler-errors private project

F#编译器给出一个错误,说我必须添加一个项目引用,因为我使用的类型有一个存在于该项目中的方法参数.但这种方法是私密的!

我有以下项目结构:

程序 - >库 - >子库

子库包含以下内容:

namespace SubLibrary

type Widget = { Value: int }
Run Code Online (Sandbox Code Playgroud)

包含:

namespace Library

open SubLibrary

type Banana =
    { Value: int }

    member private x.TakeWidget (w: Widget) = ()
Run Code Online (Sandbox Code Playgroud)

程序包含:

open Library

[<EntryPoint>]
let main argv = 
    printfn "%A" argv

    let banana = { Value = 42 }
    0
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

error FS0074:
The type referenced through 'SubLibrary.Widget' is defined in an assembly that is not referenced.
You must add a reference to assembly 'SubLibrary'
Run Code Online (Sandbox Code Playgroud)

但这种TakeWidget方法是私密的!

我试着Banana换成一个班级,而不是一个唱片,但这并没有什么区别.

作为一个实验,我创建了一个名为CLibrary的C#版本的:

using SubLibrary;

namespace CLibrary {
    public class CBanana {
        int m_value;

        public CBanana(int value) {
            m_value = value;
        }

        private void TakeWidget(Widget w) {
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我改变程序使用CBanana而不是Banana:

open Library

[<EntryPoint>]
let main argv = 
    printfn "%A" argv

    let banana = CBanana 42
    0
Run Code Online (Sandbox Code Playgroud)

现在我没有收到错误.事实上,使用C#我可以将该方法公之于众,只要我不尝试编译对它的调用,就没有错误.

为什么编译器坚持要添加对SubLibrary的引用?当然,我可以继续做它告诉我做的事情,为了安静的生活,但SubLibrary图书馆的私人实施细节,不应该暴露给程序.

scr*_*wtp 2

实际上,当我尝试使用类而不是记录时,它成功了(F# 3.1):

type BananaClass (value:int) = 
    member private x.TakeWidget (w: Widget) = ()
    member x.Value = value
Run Code Online (Sandbox Code Playgroud)

您也可以使用记录来解决它 - 您需要将私有成员移动到单独的模块中并将其作为类型增强:

type Banana = { Value: int }

module Ext =
    type Banana with
        member x.TakeWidget (w: Widget) = ()
Run Code Online (Sandbox Code Playgroud)

在您打开模块之前,编译器不会抱怨缺少依赖项Ext

我不太清楚为什么编译器首先会抱怨。可能是它的怪癖之一。我在生成的 IL 中找不到任何严重可疑的内容(除了令人惊讶的事实之外,F# 编译器将私有成员和内部成员标记为 IL 中的内部成员 - 事实证明这在这里没有任何后果)。