I'm trying to figure out how to use an F# library from a C# assembly, I have used C# quite a bit, but have never used F#.
Here is the F# Class..
namespace FLib
type Class1() =
member this.square(x)=x*x
member this.doit(x, op) = List.map op (Seq.toList(x))|>List.toSeq
member this.squareAllDirect(x) = List.map this.square (Seq.toList(x))|>List.toSeq
member this.squareAllIndirect(x) = this.doit x, this.square
Here is the C# using it
class Program
{
static void Main(string[] args)
{
FLib.Class1 f = new FLib.Class1();
List<int> l=new List<int>(){1,2,3,4,5};
var q =f.squareAllDirect(l);
var r = f.squareIndirect(l);
foreach (int i in r)
Console.Write("{0},",i);
Console.ReadKey();
}
}
The squareAllDirect function works as expected... but the squareAllIndirect call from c# has an exception:
The Type argument for method 'FLib.Class1.squareAllIndirect (System.Tuple,Microsoft.FSharp.Core.FSharpFunc'2>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
It looks you are expecting your squareAllIndirect function to take and returns a int seq
However if you mouse over it you will see it takes and returns a int seq * (int -> int)
Tuple is lower precedence than function call so x is passed as both arguments to doit.
You need to surround the parameters of your function call in ().
member this.squareAllIndirect(x) = this.doit(x, this.square)
That will ensure you take and return what you expect.
Related
Want feedback if i`m correct here?
Use void if you are not returning anything in a method,
otherwise
Name your data types used in the method criteria before method name.
use Return in the method before the calculation or output.
So something like this.
static int MyMethod(int x)
{
return 5 + x;
}
static void Main(string[] args)
{
Console.WriteLine(MyMethod(3));
}
// Outputs 8 (5 + 3)
What if my method has ints and doubles?
Do I write as follows? (another words do I have to mention every type i`m using prior to the method name?
static int double myMethod (int x, double y)
Even with that I dont know when is a method void? It seems my methods all return values.
Isnt the following returning the values of the arguments? So why should I label it void?
static void MyMethod(string fname, int age)
{
Console.WriteLine(fname + " is " + age);
}
static void Main(string[] args)
{
MyMethod("Liam", 20);
MyMethod("Jenny", 25);
MyMethod("Tom", 31);
}
I can only think that a void means there is no new calculation being done in the actual method body, passing arguments into a method and spitting them out for user viewing does not mean its "returning a value", I dont know what i`m talking about.
Let's be completely clear about what these bullets mean.
Use void if you are not returning anything in a method, otherwise
In this context, "return" means that the method provides an output that can be assigned to a variable by the caller. For example
int Return10()
{
return 10;
}
...allows the caller to do this:
int x = Return10();
Console.WriteLine(x); //Outputs "10"
A method should "return" void when its results cannot be assigned. For example, if the results are printed on the screen.
void Print10()
{
Console.WriteLine("10"); //Prints 10 to the screen
}
...which allows the caller to do this:
Print10();
You cannot assign it because it doesn't return anything. This doesn't work:
int x = Print10(); //Compiler error
Name your data types used in the method criteria before method name.
A method can return exactly one value or object. So "types" here is wrong. You can only specify one type.
Use return in the method before the calculation or output.
This is a little misleading. The return keyword should be followed by an expression which can be assigned.
int Return10()
{
return 10 + 10; //Is okay because it's an expression and could be assigned
}
int Return10()
{
var x = 10 + 10;
return x; //This is also okay; in fact it does exactly the same thing as the previous example
}
int Return10()
{
return Console.WriteLine("10"); //Compiler error; can't be assigned to anything.
}
By the way, a method can also output something and return it:
int WriteAndReturn10()
{
int x = 10;
Console.WriteLine(x);
return x;
}
I am going to address the following
What if my method has ints and doubles? Do I write as follows?
(another words do I have to mention every type i`m using prior to the
method name?
There are no built in ways or syntax to return more than one type from a method as the return parameter.. This is basically historical and has been this way since dinosaurs roamed the earth.
However, there are lots of options that achieve the same result. For instance, you could use a custom struct, you could use out parameters, you could use a class, or a delegate parameter of some kind. However, a modern succinct approach might be to use a Value Tuple:
static (int someInt, double someDouble) myMethod (int x, double y)
{
return (x,y);
}
Fun Fact : even though this looks like you a returning more than one type, you are actually just invoking a special syntax that wraps your return parameters in a single type of struct
Usage
var result = myMethod(1,2.2);
Console.WriteLine(result.someInt);
Console.WriteLine(result.someDouble);
Or if you want to get fancy, you can use the newer deconstructed syntax
var (someInt, someDouble) = myMethod(1,2.2);
Console.WriteLine(someInt);
Console.WriteLine(someDouble);
Additional Resources
return (C# Reference)
Methods (C# Programming Guide)
Tuple types (C# reference)
out parameter modifier (C# Reference)
ref (C# Reference)
Using Delegates (C# Programming Guide)
Suppose I have this class:
public class Function {
public int argc; //number of arguments of the function
public float[] argv;
public Func<float> f; //attribute to store a function (e.g. Sin(x) or Pow(a, b))
}
I want to create instances of Function that hold different functions, like Sin(x) or Pow(a, b), but I don't know how to bind an existing function (with any number of arguments) to a Func. Obviously its declaration would not always be Func<float> but Func<float, float>, Func<float, float, float>, etc.
I've looked for Func, delegate, Action but still didn't figure out how to have this "function capsule" that can hold and execute functions with different number of arguments. For simplicity I consider the only input and output type is float.
I'm thinking about using something like Func<List<float>> but I want to know if there is a better option.
I want to suggest an answer that fits more accurately the scenario described by the OP. The key is in the usage of Delegate.DynamicInvoke which lets you pass an indefinite number of arguments to a delegate.
public class Function<TReturn> {
private readonly object[] _argv;
private readonly Delegate _func;
public Function(Delegate func, params object[] args) {
_func = func;
_argv = args;
}
public TReturn Run() {
object v = _func.DynamicInvoke(_argv);
return (TReturn)v;
}
}
And its usage lets you decide dynamically the number of arguments you wish to pass:
var s = new Function<double>((Func<double, double>)(x => Math.Sin(x)), 1 );
Console.WriteLine(s.Run()); // prints 0.8414709848078965
var p = new Function<double>((Func<double, double, double>)((a, b) => Math.Pow(a, b)), 2, 3);
Console.WriteLine(p.Run()); // prints 8
var d = new Function<string>((Func<string, double, string>)((a, b) => a + b.ToString()), "hello, ", 42);
Console.WriteLine(p.Run()); // prints "hello, 42"
Note that type checking is only performed at run-time when calling Function.Run() and not when constructing the Function object because of its dynamic nature. If you know for sure that all passed arguments will always be of the same type, you could enforce that statically by adding a TArg generic type.
Why does this program show an error for using seq:
class Program
{
delegate double Sequence(int r);
void F(ref Sequence seq) // Here
{
Sequence seq2 = r =>
{
if (r % 2 == 0)
return seq(r); // Here
else
return seq(2 * r); // Here
};
seq = seq2;
}
static void Main()
{
}
}
Error CS1628 Cannot use ref, out, or in parameter 'seq' inside an
anonymous method, lambda expression, query expression, or local
function CsharpRefLambdaTest
The problem is with that the parameter seq is a reference type. But why is it wrong? what't the problem with a reference seq? If seq is not reference the program has no errors.
Is there any way to correct the program while keeping seq as a reference?
The program is just an test and it is not going to do anything.
================
I need to use the value of seq to define a new Sequence seq2 and then assign seq = seq2. But the values of seq are not usable. If the values of seq are not going to be usable why does C# allow seq to be a reference at all?
===============================
Edit:
The program above is just simplified version of the following:
class Program
{
delegate double Sequence(int r);
Sequence G(Sequence seq)
{
Sequence seq2 = r =>
{
if (r % 2 == 0)
return seq(r);
else
return seq(2 * r);
};
return seq2;
}
void F(ref Sequence seq)
{
seq = G(seq);
}
static void Main()
{
}
}
But I don't understand why I cannot remove G and instead add the defining code of G insideF`.
the error message here is: "CS1628 Cannot use ref, out, or in parameter 'seq' inside an anonymous method, lambda expression, query expression, or local function" - seq2 is the lambda expression; it has nothing to do with reference types, but rather: lifetimes. You could, after all, call it like:
void Foo() {
Sequence bar = SomeMethod; // bar is a LOCAL of Foo
F(ref bar);
// not shown: perhaps do something with bar, perhaps not
}
at which point, F would need to somehow create a lambda that contains within it a reference to a position on the stack (a reference to the local bar). Now note that this lambda, being an object, could outlive Foo, and bar would be an undefined - and possibly reused - memory location.
So: you can't "capture" parameters that are passed as ref, in our out, where I'm using "capture" loosely here to mean "use within the scope of a lambda or anonymous method that forms an expression-tree, delegate expression; or within an iterator block or async continuation".
Just remove the ref. You don't need it, and it isn't helping. If your intention is to change the delegate, then consider instead returning the composed delegate.
as an alternative workaround: snapshot the value and capture the snapshot:
void F(ref Sequence seq)
{
var tmp = seq;
seq = r =>
{
if (r % 2 == 0)
return tmp(r);
else
return tmp(2 * r);
};
}
this avoids the problematic scenario because the snapshot dereferences the ref parameter, meaning: there is now no possibility that we're capturing a stack location.
Would anyone be so kind to post the equivalent Java code for a closure like this one (obtained using C#) with anonymous inner classes?
public static Func<int, int> IncrementByN()
{
int n = 0; // n is local to the method
Func<int, int> increment = delegate(int x)
{
n++;
return x + n;
};
return increment;
}
static void Main(string[] args)
{
var v = IncrementByN();
Console.WriteLine(v(5)); // output 6
Console.WriteLine(v(6)); // output 8
}
Furthermore, can anyone explain how partial applications can be obtained if lexical closures are available and viceversa? For this second question, C# would be appreciated but it's your choice.
Thanks so much.
There is no closure yet in Java. Lambda expressions are coming in java 8. However, the only issue with what you're trying to translate is that it has state, which not something that lamba expressions will support i don't think. Keep in mind, it's really just a shorthand so that you can easily implement single method interfaces. You can however still simulate this I believe:
final AtomicInteger n = new AtomicInteger(0);
IncrementByN v = (int x) -> x + n.incrementAndGet();
System.out.println(v.increment(5));
System.out.println(v.increment(6));
I have not tested this code though, it's just meant as an example of what might possibly work in java 8.
Think of the collections api. Let's say they have this interface:
public interface CollectionMapper<S,T> {
public T map(S source);
}
And a method on java.util.Collection:
public interface Collection<K> {
public <T> Collection<T> map(CollectionMapper<K,T> mapper);
}
Now, let's see that without closures:
Collection<Long> mapped = coll.map(new CollectionMapper<Foo,Long>() {
public Long map(Foo foo) {
return foo.getLong();
}
}
Why not just write this:
Collection<Long> mapped = ...;
for (Foo foo : coll) {
mapped.add(foo.getLong());
}
Much more concise right?
Now introduce lambdas:
Collection<Long> mapped = coll.map( (Foo foo) -> foo.getLong() );
See how much nicer the syntax is? And you can chain it too (we'll assume there's an interface to do filtering which which returns boolean values to determine whether to filter out a value or not):
Collection<Long> mappedAndFiltered =
coll.map( (Foo foo) -> foo.getLong() )
.filter( (Long val) -> val.longValue() < 1000L );
This code is equivalent I believe (at least it produces the desired output):
public class Test {
static interface IncrementByN {
int increment(int x);
}
public static void main(String[] args) throws InterruptedException {
IncrementByN v = new IncrementByN() { //anonymous class
int n = 0;
#Override
public int increment(int x) {
n++;
return x + n;
}
};
System.out.println(v.increment(5)); // output 6
System.out.println(v.increment(6)); // output 8
}
}
Assuming we have a generic function interface:
public interface Func<A, B> {
B call A();
}
Then we can write it like this:
public class IncrementByN {
public static Func<Integer, Integer> IncrementByN()
{
final int n_outer = 0; // n is local to the method
Func<Integer, Integer> increment = new Func<Integer, Integer>() {
int n = n_outer; // capture it into a non-final instance variable
// we can really just write int n = 0; here
public Integer call(Integer x) {
n++;
return x + n;
}
};
return increment;
}
public static void main(String[] args) {
Func<Integer, Integer> v = IncrementByN();
System.out.println(v.call(5)); // output 6
System.out.println(v.call(6)); // output 8
}
}
Some notes:
In your program, you capture the variable n by reference from the enclosing scope, and can modify that variable from the closure. In Java, you can only capture final variables (thus capture is only by value).
What I did here is capture the final variable from the outside, and then assign it into a non-final instance variable inside the anonymous class. This allows "passing info" into the closure and at the same time having it be assignable inside the closure. However, this information flow only works "one way" -- changes to n inside the closure is not reflected in the enclosing scope. This is appropriate for this example because that local variable in the method is not used again after being captured by the closure.
If, instead, you want to be able to pass information "both ways", i.e. have the closure also be able to change things in the enclosing scope, and vice versa, you will need to instead capture a mutable data structure, like an array, and then make changes to elements inside that. That is uglier, and is rarer to need to do.
Given the F# higher order function (taking a function in parameter):
let ApplyOn2 (f:int->int) = f(2)
and the C# function
public static int Increment(int a) { return a++; }
How do I call ApplyOn2 with Increment as parameter (from C#)?
Note that ApplyOn2 is exported as Microsoft.FSharp.Core.FSharpFunc<int,int> which do not match with Increment's signature.
To get an FSharpFunc from the equivalent C# function use:
Func<int,int> cs_func = (i) => ++i;
var fsharp_func = Microsoft.FSharp.Core.FSharpFunc<int,int>.FromConverter(
new Converter<int,int>(cs_func));
To get a C# function from the equivalent FSharpFunc, use
var cs_func = Microsoft.FSharp.Core.FSharpFunc<int,int>.ToConverter(fsharp_func);
int i = cs_func(2);
So, this particular case, your code might look like:
Func<int, int> cs_func = (int i) => ++i;
int result = ApplyOn22(Microsoft.FSharp.Core.FSharpFunc<int, int>.FromConverter(
new Converter<int, int>(cs_func)));
If you would like to provide a more friendly interop experience, consider using the System.Func delegate type directly in F#:
let ApplyOn2 (f : System.Func<int, int>) = f.Invoke(2)
You would be able to call your F# function very easily in C# like this:
MyFSharpModule.ApplyOn2(Increment); // 3
There is an issue with the Increment function as you have written it, however. You need the prefix form of the increment operator in order for your function to return the correct result:
public static int Increment(int a) { return ++a; }
Just create reference to your assembly:
#r #"Path\To\Your\Library.dll"
let ApplyOn2 (f:int->int) = f(2)
ApplyOn2 Library.Class.Increment