Search code examples
f#ncrunch

Can't access a partially applied function with in a class


I'm extremely new to F# and was playing around with the stack calculator on the F# for fun and profit (excellent site). I was trying to figure out how to have a test project and class. I have a test class with this method:

open NUnit.Framework
open FSharpDoodles.MainProgram

[<TestFixture>]
type ProgramTests()=

    [<Test>]
    member self.FirstTest()=
        // Create some stacks
        let EMPTY = StackContents []
        let try1 = push 1.0 EMPTY      // OK
        let try2_partial = push 1.0    // OK
        let try2 = try2_partial EMPTY  // OK - does same as ONE below
        let stackWith1 = ONE EMPTY     // FAILS: ONE is null
        ()

The code it is testing is thus:

module FSharpDoodles.MainProgram 

type Stack = StackContents of float list

let push x (StackContents contents) =
    StackContents ( x::contents )

let ONE = push 1.0

So, if I'm calling a function and getting a value (call to push), it works. And if I create a partially applied function in the class (try2_partial), that works. But when I'm referencing ONE, which is returning a partially applied function, ONE is null.

Why is that?

The Rest of The Story

I'm using NCrunch as my test runner. It is entirely possible that it is causing a problem.

Edit

As suggested by John, I tried this in FSI and get the same issue. Below is the progressive application of the same test code:

open FSharpDoodles.MainProgram
let EMPTY = StackContents [];;


val EMPTY : FSharpDoodles.MainProgram.Stack = StackContents []

> let try1 = push 1.0 EMPTY;;


val try1 : Stack = StackContents [1.0]

> let try2_partial = push 1.0;;


val try2_partial : (Stack -> Stack)

> let try2 = try2_partial EMPTY;;


val try2 : Stack = StackContents [1.0]

> let stackWith1 = ONE EMPTY;;
System.NullReferenceException: Object reference not set to an instance of an object.
   at <StartupCode$FSI_0006>.$FSI_0006.main@()
Stopped due to error

I made a reference to the SUT for FSI under Tools|Options -> F# Interactive, F# Interactive options. I used -r and referenced the assembly in debug\bin.

As I mentioned, I very new to this F# stuff and I might be making some very rookie mistake related to how I'm putting together either of the modules.

Update 2

Based on John's comment, I tried moving the code from an .exe to a .dll (library). It worked fine. So, the issue is related to referencing the .exe. So the question now evolves into why this makes a difference (exe vs dll)?


Solution

  • The reason it didn't work is that I was referencing an EXE and not a DLL. Same code in a DLL works fine. Thanks to John Palmer question for getting me to investigate that angle and then for providing the explanation (see the comments).