【问题标题】:Is it possible to have private functions (let definitions) in F# modules?F# 模块中是否可以有私有函数(let 定义)?
【发布时间】:2011-09-11 15:38:14
【问题描述】:

我想让applyAndTruncate 对外界隐藏(即对Scoring 模块之外的任何东西),因为我实际上只将它用作bestKPercent 和worstKPercent 的主干。是否可以隐藏它?如果没有,完成我想做的事情的 F#ish 方式是什么?

module Scoring
    let applyAndTruncate f percentage (scoredPopulation:ScoredPopulation) : ScoredPopulation =
      if (percentage < 0.0 || percentage > 1.0) then
        failwith "percentage must be a number between 0.0 and 1.0"

      let k = (int)(percentage * (double)(Array.length scoredPopulation))

      scoredPopulation
      |> f
      |> Seq.truncate k
      |> Seq.toArray

    let bestKPercent = applyAndTruncate sortByScoreDesc
    let worstKPercent = applyAndTruncate sortByScoreAsc

【问题讨论】:

  • 我对 F# 几乎一无所知,但也许 the F# spec 会有所帮助。看来您可以添加可访问性注释来让绑定。

标签: .net f#


【解决方案1】:

是的。 let private myfunc = 会做到的。

【讨论】:

  • 对于递归函数,你应该把rec放在private之前
【解决方案2】:

也可以使用signature files指定对应实现文件的公共接口。然后的想法是,在实现固化之前,您不必担心可访问性。老实说,我从未使用过它们,但它们在 F# 编译器源代码中被广泛使用(可能只是因为我对许多其他语言中使用的实现站点风格感到满意,而具有原始 ML 经验的人会放心带有签名文件;还有you do get some extra features 带有签名文件,虽然没有什么特别引人注目的)。

因此,如果您的 Scoring 模块是在名为 Scoring.fs 的文件中实现的,那么您将有一个名为 Scoring.fsi 的相应签名文件,如下所示:

namespace NS //replace with you actual namespace; I think you must use explicit namespaces
module Scoring =
    //replace int[] with the actual ScoredPopulation type; I don't think you can use aliases
    val bestKPercent : (float -> int[] -> int[])
    val worstKPercent : (float -> int[] -> int[])

【讨论】:

  • 如果我可以在 Visual Studio 中右键单击 *.fs 文件并“生成签名文件”,我可能会使用签名文件。事实上,如果我想要一个,我要么必须查找语法以手动编写它,要么必须查找命令行参数让 F# 编译器为我生成一个,然后将文件添加到项目。到目前为止,我还没有强烈地感到需要打扰。
猜你喜欢
  • 1970-01-01
  • 2011-11-11
  • 2015-10-06
  • 2019-08-04
  • 2010-10-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-29
  • 1970-01-01
相关资源
最近更新 更多