Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否可以在内部类型上为程序集中的所有文件提供F#运算符重载?_F# - Fatal编程技术网

是否可以在内部类型上为程序集中的所有文件提供F#运算符重载?

是否可以在内部类型上为程序集中的所有文件提供F#运算符重载?,f#,F#,我有一些强制执行数值范围的类型,我在单个项目的许多文件中使用它们。它们看起来像这样: [] 类型非负货币= 新的(x)= 如果x

我有一些强制执行数值范围的类型,我在单个项目的许多文件中使用它们。它们看起来像这样:

[]
类型非负货币=
新的(x)=
如果x<0米,则为无效“x”“Ruh roh…”
{Value=x}
val值:十进制
静态成员(+)(x:NonNegativeMoney,y:NonNegativeMoney)=非negativeMoney(x.Value+y.Value)
现在,我想将这些类型设置为程序集的内部类型,只将我的OO类型模型保留为公共类型。但是,当我将这些类型转换为内部类型时,出现了以下编译器错误:

成员或对象构造函数“op_Addition”不是公共的。私有的 只能从声明类型内访问成员。受保护的 只能从扩展类型访问成员,并且不能 从内部lambda表达式访问

问题中已经说明了这一点的原因。答案中提出的解决方案是将类型设置为内部类型。这适用于该问题中OP的场景,其中运算符的使用仅限于同一文件中的某个类型。然而,我似乎找不到一种方法使它工作,以便操作员可以从我项目中的所有文件访问。如果我使用签名文件,它在文件内工作,但在文件间不工作


是否有任何方法可以使此工作正常,使类型在程序集内部,但在项目中的文件中可见?我希望保留运算符,因为我正在使用库函数,如
Seq.sum
,这些函数要求对要求和的类型使用运算符。

您可以在模块中定义重载,而不是在类型中定义重载:

[<Struct>]
type internal NonNegativeMoney =
    new(x) =
        if x < 0m then invalidArg "x" "Ruh-roh..."
        { Value = x }
    val Value : decimal

let internal (+) (x: NonNegativeMoney) (y: NonNegativeMoney) = NonNegativeMoney(x.Value + y.Value)
[]
类型内部非负项=
新的(x)=
如果x<0米,则为无效“x”“Ruh roh…”
{Value=x}
val值:十进制
设内部(+)(x:NonNegativeMoney)(y:NonNegativeMoney)=非负money(x.Value+y.Value)
…但这将覆盖普通(+)运算符,这可能就是您排除它的原因。使用自定义运算符(如++)可能是一种合理的折衷


您可以通过标记模块
[]

使操作员可用于整个项目。您是否尝试使用
InternalsVisibleTo
属性对其进行注释?@s952163我要注释什么?我认为
InternalsVisibleTo
是用于组件间使用的。我正在尝试从同一程序集中使用运算符。你能详细说明一下吗?我明白了。您将为assembly属性sg添加注释。像这样的“[]”,您可以尝试一下,但正如您所说的,您的用例略有不同。
InternalsVisibleTo
属性在构造函数中使用程序集名称,所以不要认为我可以使用
NonNegativeMoney
。也许我可以将数字类型拉入一个新程序集,使用签名文件将内容设置为内部(根据另一个答案),然后添加
InternalsVisibileTo
属性,引用我的主程序集。感觉很脏。希望有更好的方法。我在之前的评论中提出的解决方案对运营商仍然不起作用。我将类型移动到新程序集,添加sig文件(使其成为内部文件),然后使用
InternalsVisibleTo
,但现在我得到
BlahBlahType.fs(10,10):[FS0001]成员或对象构造函数“op_Addition”不是公共的。只能从声明类型内访问私有成员。受保护的成员只能从扩展类型访问,不能从内部lambda表达式访问。
我可以创建该类型的值(因此我知道IVT正在工作),但op使用仍然失败。感谢您的回答。我实际上没有考虑过这样做,但我认为这并不能解决我的问题,因为我使用了库函数,如
sum
sumBy
,它们需要对类型进行
op_Addition
。我将编辑该问题以包含该细节。