0

Having found no examples online of NLopt being used in F#, I've been trying to convert the example given on NLoptNet from C# to F#. Having no familiarity with C# and very little with F#, I've been butchering it pretty badly.

Here is what I have so far:

open NLoptNet
open System


let solver = new NLoptSolver(NLoptAlgorithm.LN_COBYLA, uint32(1), 0.001, 100)
solver.SetLowerBounds([|-10.0|])
solver.SetUpperBounds([|100.0|])

let objfunc (variables : float array) = 
    Math.Pow(variables.[0] - 3.0, 2.0) + 4.0

solver.SetMinObjective(objfunc)

let initial_val = [|2.|]
let finalscore = ref System.Nullable()   // ERROR
let result = solver.Optimize(initial_val,  finalscore)

Here is the description of the error:

Successive arguments should be separated by spaces or tupled, and arguments involving function or method applications should be parenthesized

To be more specific, I'm trying to translate the following three lines of C# to F#:

double? finalScore;
var initialValue = new[] { 2.0 };
var result = solver.Optimize(initialValue, out finalScore);

Any ideas?

ildjarn
  • 62,044
  • 9
  • 127
  • 211
  • 3
    I suspect that `ref (System.Nullable())` or `ref <| System.Nullable()` will solve your problem – John Palmer Jul 19 '16 at 00:07
  • Terrific. Can you please post as answer so I can hit the checkmark? Thank you! – professor bigglesworth Jul 19 '16 at 00:20
  • 2
    I wonder if you could take the out parameter without creating a ref cell. something like this `let finalscore, result = solver.Optimize(initial_val)`. – s952163 Jul 19 '16 at 01:47
  • Hey wow... You're right. I'm assuming ref cells are something to be avoided? – professor bigglesworth Jul 19 '16 at 01:57
  • Generally you don't need to use `ref` from F# 4.0. If you want a mutable you can just say `let mutable x = 5`. For this particular case the out parameter can be deconstructed (pattern matched) on the left side. It's useful for various C# tryParse functions that return true or false for example. Or you can throw it away of course. – s952163 Jul 19 '16 at 03:26

2 Answers2

5

This error is due to the way that F# handles precedence - adding more brackets or some operators to clarify the order in which things are applied fixes the problem.

2 possible fixes are

ref (System.Nullable())

or

ref <| System.Nullable()
John Palmer
  • 25,356
  • 3
  • 48
  • 67
3

Just for completeness' sake here's a third possible fix:

let finalscore, result = solver.Optimize(initial_val)

This takes advantage of the fact the F# can treat the out parameter as a return value (in a tuple). I'm sure that there might be a case where an actual ref cell might be necessary. In recent F# mutable usually is enough. For some discussion see:

MSDN reference

SO Discussion 1

SO Discussion 2

Fun&Profit reference

Community
  • 1
  • 1
s952163
  • 6,276
  • 4
  • 23
  • 47