I'm messing around with C# function conversion in F#. I know there are more idiomatic ways to do this (including using the static
methods on System.String
), but this is a learning exercise. In C#, if I want to create a predicate based on an instance method of an object, it's straightforward
var predicate = MakeEquals("hello");
Console.WriteLine(predicate("HELLO", StringComparison.OrdinalIgnoreCase)); // True
Func<string, StringComparison, bool> MakeEquals(string s) => s.Equals;
In F#, this doesn't compile:
let makeEquals (s: string) : string -> StringComparison -> bool =
let f = Func<string, StringComparison, bool>(s.Equals)
FuncConvert.FromFunc(f)
error FS0001: This expression was expected to have type
'StringComparison -> bool'
but here has type
'bool'
This error confuses me, especially since this works:
let makeEquals (s: string) : string -> bool =
let f = Func<string, bool>(s.Equals)
FuncConvert.FromFunc(f)
And I have no trouble calling the overloaded method
"hello".Equals("HELLO", StringComparison.OrdinalIgnoreCase) // true
What am I doing wrong?
The type of that overload of s.Equals
is actually string * StringComparison -> bool
, not string -> StringComparison -> bool
. That is, from F# point of view, the overload accepts a single argument that is a tuple, not two arguments.
So this would work:
Func<string * StringComparison, bool>(s.Equals)
Or you can use a wrapper function for currying it:
Func<string, StringComparison, bool>(fun a b -> s.Equals(a, b))