C# - F# interoperability, how to get result instead of FSharpFunc - c#

I'm learning F# and would like to write simple F# library which can be consumed from C# application. It works as expected for trivial F# functions e.g.
let Square x = x * x
From C# I can consume it and get the expected value:
var sqaredNumber = MyFSharpLibrary.Square(5);
However when I use a Sequence / IEnumerable<T> as function parameter I got FSharpFunc object instead of the result.
Here is my function:
let FilterEvenNumbers input = Seq.filter(fun x -> x % 2 = 0)
And this is how I try to use it from C# code:
var numbers = new int[] { 1, 2, 3, 4 };
var filteredNumbers = MyFSharpLibrary.FilterEvenNumbers(numbers);
Instead of value filteredNumbers contains FSharpFunc object. I could use method Invoke on that object but would like to avoid extra complexity.
How can I achieve that ?

This is because your function declaration returns a function. If you enter it into dotnet fsi you'll see the signature:
val FilterEvenNumbers: input: 'a -> (seq<int> -> seq<int>)
See the parentheses? That means a single FSharpFunc object is returned, and it is the function that you call with input.
As you can see, input isn't passed to the filtering function, nor is its type associated at all with the inferred parameterized types for Seq.
To fix this, you need to pass input to Seq.filter.

Related

Methods for dynamically creating an array in C#

First, I don't have much experience in .Net - especially within the last 7 years.
I'm trying to develop an application and would to incorporate another library (https://github.com/Giorgi/Math-Expression-Evaluator)
That library allows me to evaluate math expressions like Evaluate("a+b", a: 1,b: 1). The method signature is public decimal Evaluate(string expression, object argument = null)
I would like to understand better how .Net translates comma-separated arguments into a single "argument".
I'm not sure how to create that argument dynamically.. for example, iterating through a list of values and creating an object that will match the appropriate argument for that signature.
I'm really just looking for pointers for documentation and more information.. Thanks for anything.
EDIT: Sorry.. purposely left it broad because I wasn't looking for people to do my work for me.. just can't seem to find a starting point to do my own research.
The method is called like
dynamic engine = new ExpressionEvaluator() ;
engine.Evaluate("(c+b)*a", a: 6, b: 4.5, c: 2.6)) ;
In the body of Evalute() is this code (which turns that argument into a Dictionary of String, Decimal pairs.
if (argument == null)
{
return new Dictionary<string, decimal>();
}
var argumentType = argument.GetType();
var properties = argumentType.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(p => p.CanRead && IsNumeric(p.PropertyType));
var arguments = properties.ToDictionary(property => property.Name,
property => Convert.ToDecimal(property.GetValue(argument, null)));
return arguments;
What I'd like to be able to do is parse a String like "a:1,b:2" and turn it into an object that matches that Evaluate() signature.
That library is using high level magic... Very high level :-)
The trick is that the class is declared as:
public class ExpressionEvaluator : DynamicObject
So it is a class that implements the dynamic magic introduced in .NET 4.0
Now... In the class there are two Evaluate methods:
public decimal Evaluate(string expression, object argument = null)
and
private decimal Evaluate(string expression, Dictionary<string, decimal> arguments)
The only method normally visible and usable is the first one. It is used like:
engine.Evaluate("a + b + c", new { a = 1, b = 2, c = 3 });
The new { ... } creates an anonymous object, that is then "unpacked" here through the use of reflection to a Dictionary<string, decimal> to be fed to the private Evaluate().
If you try to use the other notation, the one like:
engine.Evaluate("a + b + c", a: 1, b: 2, c: 3 });
then the .NET can't match the method to the public Evaluate() that is present, but the class, being a subclass of DynamicObject, causes the C# compiler to write some "magic" code that launches this method (that is still implemented by the ExpressionEvaluator):
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
That first checks that we want to call Evaluate:
if (nameof(Evaluate) != binder.Name)
and if we are trying to call Evaluate, it unpacks the parameters to a new Dictionary<string, decimal>() and then calls the private Evaluate().
As a sidenote, to use the "dynamic" way of writing Evaluate you have to declare the engine variable like;
dynamic dynamicEngine = new ExpressionEvaluator();
So using the dynamic variable type.
Now... As the library is written you can:
Use an anonymous object, with the problem that anonymous objects must have their "shape" defined at compile time (so at compile time you must know that you will need a a, a b and a c. You can't need a d at runtime if you didn't create a new { a, b, c, d } at compile time). See for example a response I gave three years ago about how to create dynamic anonymous types at runtime. One of the reasons I gave for that block of code was:
there are parts of the .NET framework that heavily use reflection to render objects (for example all the various datagrids). These parts are incompatible with dynamic objects and often don't support object[]. A solution is often to encapsulate the data in a DataTable... or you can use this :-)
Note that in one of the comments to that response there is a link to a modified version of my code used by one of the many implementations of Dynamic.Linq.
Use a non-anonymous object (a new Foo { a = 1, b = 2 c = 3 }). The library doesn't make distinctions between anonymous and non-anonymous objects. So same limitation as before, because at compile time you need a Foo class with the right number of parameters
Use the dynamic notation. Sadly even that is quite static. You can't easily add new parameters, that for the number and name of the "variables" must be defined at compile time.
A possible solution is to modify the source code (it is a single file) and make public this method:
private decimal Evaluate(string expression, Dictionary<string, decimal> arguments)
then you can easily and dynamically populate the Dictionary<string, decimal> arguments

Extract function name from a function

How can I create a function called getFuncName that takes a function of type (unit -> 'a) and returns its name.
I was talking to one of the C# devs and they said you could use the .Method property on a Func type as shown in an example here.
I tried to convert this to F# :
for example convert (unit -> 'a) to a type Func<_> then call the property on it but it always returns the string "Invoke".
let getFuncName f =
let fFunc = System.Func<_>(fun _ -> f())
fFunc.Method.Name
let customFunc() = 1.0
// Returns "Invoke" but I want it to return "customFunc"
getFuncName customFunc
A bit of background to this problem is:
I have created an array of functions of type (unit -> Deedle.Frame). I now want to cycle through those functions invoking them and saving them to csv with the csv name having the same name as the function. Some hypothetical code is below:
let generators : (unit -> Frame<int, string>) array = ...
generators
|> Array.iter (fun generator -> generator().SaveCsv(sprintf "%s\%s.csv" __SOURCE_DIRECTORY__ (getFuncName generator)))
This is being used in a scripting sense rather than as application code.
Not sure how you searched for information, but the first query to the search engine gave me this response:
let getFuncName f =
let type' = f.GetType()
let method' = type'.GetMethods() |> Array.find (fun m -> m.Name="Invoke")
let il = method'.GetMethodBody().GetILAsByteArray()
let methodCodes = [byte OpCodes.Call.Value;byte OpCodes.Callvirt.Value]
let position = il |> Array.findIndex(fun x -> methodCodes |> List.exists ((=)x))
let metadataToken = BitConverter.ToInt32(il, position+1)
let actualMethod = type'.Module.ResolveMethod metadataToken
actualMethod.Name
Unfortunately, this code only works when F# compiler does not inline function body into calling method.
Taken from here
Although there may be a more simple way.

Assign a variable the result of dynamic function call in C#

In JavaScript I can assign a value to a variable by dynamically creating a function. Such as
var name = (function () { name="bob"; return name; }());
I'm fairly certain that with C# 4.0 the same type of thing is possible. Could someone show me the syntax of how the same line above would look in C#?
Also, if you could jog my memory on what the proper term for creating this type of dynamic function is, it would be much appreciated!
Thanks for your help!
PS: It's likely this question has been asked before, but since I was unclear on the nomenclature I may have missed finding it. If that's the case, I apologize!
You can use anonymous methods:
Func<string> anonymousFunction = () => { string name = "bob"; return name; };
string myName = anonymousFunction();
The syntax on the first line is a lambda, which is the C#3.0 and above way of declaring anonymous methods. The above function takes no arguments, but there's nothing stopping you from including them as well:
Func<string, string> makeUppercase = x => x.ToUpper();
string upperCase = makeUppercase("lowercase");
Note that since there is only one parameter, you can elide the brackets around it. As well, since the entire method is a single return statement, you can elide both the brace brackets as well as the return statement itself.
This type of lambda is very common when using the LINQ extension methods, since many of them require a single-argument method that returns a value:
var numbers = new List<int>() { 1, 2, 3, 4 };
var divisibleByTwo = numbers.Where(num => num % 2 == 0);
To answer your actual question, that syntax is not valid in C#. If you try this:
string output = (x => x.ToUpper())("lowercase");
You'll get an error message saying "Method name expected." You have to assign the anonymous method to a delegate first.
Generally what you want to look into are Func/Actions:
http://msdn.microsoft.com/en-us/library/bb549151.aspx
http://msdn.microsoft.com/en-us/library/018hxwa8.aspx
And for that matter, lambda expressions:
http://msdn.microsoft.com/en-us/library/bb397687.aspx

FSharpChoice in C#

I am trying to use FSharpChoice type in a C# project. I have created a choice like so
var a = FSharpChoice<T1,T2,T3>.NewChoice1Of3(instofT1);
now how do I get instofT1 out of the choice type.
I see I can do a IsChoice1Of3 but how do i get to the value in the choice object?
I probably wouldn't use the type directly from C# - you can do that, but the resulting code won't be very nice. I'd probably declare my own Choice type that would look like this:
type Choice<'T1, 'T2> private (opt1, opt2) =
member x.TryGetChoice1Of2(arg:byref<'T1>) = //'
match opt1 with
| Some v -> arg <- v; true
| _ -> false
// Similar code for 'TryGetChoice2Of2'
type Choice = // static methods for creating (Choice1Of2, ...)
This uses byref parameters which appear as out parameters in C#, so you could write:
int num;
string str;
if (choice.TryGetChoice1Of2(out num)) // ...
else if (choice.TryGetChoice2Of2(out str)) // ...
else // assert(false)
This is definitely more pleasant way of working with the type from C# (and it uses pattern familiar from, for example, working with Int32.TryParse).
Cast the value to FSharpChoice<T1,T2,T3>.Choice1Of3 and use the Item property.
See Compiled Form of Union Types for Use from Other CLI Languages in the F# spec for more information about how discriminated unions are represented.
I recently started a project to make a "compatibility layer" so that FSharp.Core can be more easily consumed from C#. In particular, it makes generic discriminated unions usable from C#, for example:
var choice = Choice.New1Of3<int,string,string>(100);
int r = choice.Match(i => i + 21, s => s.Length + 1, s => s.Length + 5);
This does pattern matching on the discriminated union, similarly to how you would do it in F#, except there are no names.

C# Defining the Length of a Generic created using Reflection

I have code like this:
Type typPrecise = MostPrecise(typeof(int), typeof(double));//Evaluates to double
var varGeneric = typeof(Number<>);
var varSpecific = varGeneric.MakeGenericType(typPrecise);
dynamic nmNumber = Activator.CreateInstance(varSpecific);
The nmNumber is of dynamic type and essentially produces a Generic Number. How do I then specify the number of items in Number.
I basically want to accomplish this but by using the dynamic code above:
Number<typPrecise> whatever = new Number<typPrecise>(10);
An answer using 4.0 concepts is welcome.
Call the overload of Activator.CreateInstance that accepts constructor arguments:
dynamic nmNumber = Activator.CreateInstance(varSpecific, new object[] { 10 });
Incidentally note that the List<T>(int) constructor sets the initial capacity of the List, not the initial number of items (Count). The initial Count is always 0.

Categories

Resources