26

I'd like to make applyAndTruncate hidden from the outside world (that is, from anything outside the Scoring module), as I really only use it as backbone for bestKPercent and worstKPercent. Is it possible to hide it? If not, what is the F#ish way of accomplishing what I want to do?

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
devoured elysium
  • 101,373
  • 131
  • 340
  • 557
  • I hardly know anything about F#, but perhaps [the F# spec](http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/manual/spec.html#_Toc270597594) is helpful. It seems you can add accessibility annotations to let bindings. –  Sep 11 '11 at 15:45

2 Answers2

61

Yes. let private myfunc = will do it.

Daniel
  • 47,404
  • 11
  • 101
  • 179
13

You can also use signature files to specify the public interface of a corresponding implementation file. Then the idea is that you don't worry about accessibility until the implementation has solidified. I've honestly not ever used them, but they are used in the F# compiler source code extensively (probably just because I'm comfortable with the implementation site style used in so many other languages, whereas folks with original ML experience will be at ease with signature files; also, you do get some extra features with signature files, though nothing super compelling).

So if your Scoring module were implemented in a file named Scoring.fs, you'd have a corresponding signature file named Scoring.fsi that would look something like:

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[])
Community
  • 1
  • 1
Stephen Swensen
  • 22,107
  • 9
  • 81
  • 136
  • 7
    I might use signature files if I could right-click a *.fs file in Visual Studio and "Generate Signature File". As it is, if I want one I either have to look up the syntax to write it by hand, or I have to look up the command-line parameters to have the F# compiler generate one for me, and then add the file to the project. So far, I haven't felt the need acutely enough to bother. – Joel Mueller Sep 12 '11 at 21:23