Consider the example below. I am able to make a call to an extension method for a delegate if first I define a variable of that delegate type. But I cannot call that extension method on a delegate which is passed as an argument. I don't get why it works the first time but doesn't work the second. What am I doing wrong?
public static class Extender
{
public static Func<String, String> Compose(this Func<String, String> outer, Func<String, String> inner)
{
return input => outer(inner(input));
}
}
public class Demo
{
public void WillingToTakeStringToStringDelegate(Func<String, String> map)
{
// blah
}
public void RunMe()
{
Func<String, String> outer = x => "(outer: " + x + ")";
// this works:
var composition = outer.Compose(x => "(inner: " + x + ")");
Trace.Write(composition("!")); // ---> (outer: (inner: !))
// this doesn't work:
this.WillingToTakeStringToStringDelegate(
(x => "(outer: " + x + ")").Compose(y => "(inner: " + y + ")")
);
}
}
UPDATE
for #philologon
As long as you don't mind having to assign your lambdas to variables then yes, you can use this method for creating partial applications of functions (currying) like a boss:
public static class CurryingHelper
{
public static Func<X> Apply<A, X>(this Func<A, X> fun, A a)
{
return () => fun(a);
}
public static Func<B, X> Apply<A, B, X>(this Func<A, B, X> fun, A a)
{
return b => fun(a, b);
}
public static Func<B, C, X> Apply<A, B, C, X>(this Func<A, B, C, X> fun, A a)
{
return (b, c) => fun(a, b, c);
}
public static Func<B, C, D, X> Apply<A, B, C, D, X>(this Func<A, B, C, D, X> fun, A a)
{
return (b, c, d) => fun(a, b, c, d);
}
// etc...
}
public class Demo
{
public void RunMe()
{
Func<Int32, Int32, Int32, Int32> func = (a, b, c) => a - b + c;
var funcA1 = func.Apply(1);
Trace.Write(funcA1(2, 3)); // --> 2
Trace.Write(funcA1.Apply(2).Apply(3)()); // --> 2
}
}
There is nothing wrong with the conception, only some technical problems with the execution.
The point is that x => "(outer: " + x + ")" is not a delegate without context: it is a lambda expression that could either correspond to a delegate (of some type) or even to an expression tree. Therefore the type has to be explicitly or implicitly declared, e.g.
// this works:
this.WillingToTakeStringToStringDelegate(
((Func<string, string>)(x => "(outer: " + x + ")")).Compose(...)
);
This is the exact same reason why you cannot assign lambda functions to implicitly typed variables, e.g.
var f1 = (string s) => "Hello " + s; // does not work
Func<string, string> f2 = (string s) => "Hello " + s; // works fine
Lambda expressions in C# do not have types by themselves. For example, you can assign the lambda expression x => x != 0 to Predicate<int>, Func<int, bool>, Func<long, bool> or YourCustomDelegate.
So, whenever you use a lambda expression, you need to provide a hint to the compiler what delegate type should be used.
Examples:
This works. The hint is the type of the variable outer.
Func<String, String> outer = x => "(outer: " + x + ")";
This works. The hint is the type of the parameter inner of the Compose method.
var composition = outer.Compose(x => "(inner: " + x + ")");
This doesn't work, because no hint is provided for (x => "(outer: " + x + ")"):
this.WillingToTakeStringToStringDelegate(
(x => "(outer: " + x + ")").Compose(y => "(inner: " + y + ")")
);
The other answers are correct; I just wanted to note that the design team deliberately chose that extension methods not work on any expression that had no type -- so, no extension methods on lambdas, anonymous methods, null or method groups, or any dynamic expression.
In fact it goes farther than that; the expression on the left of the dot must be convertible to the first parameter by an identity, implicit reference or boxing conversion. So in other words:
enum E { }
static class Ext
{
public static E X(this E e) { return e; }
}
// Legal
E e1 = 0;
// Legal
E e2 = e1.X();
// No way José.
E e3 = 0.X();
That is not an identity, reference or boxing conversion.
The language design principles at work here are first, no nasty surprises. Extension methods are a late addition to the language and the design team wanted to be very careful about not adding situations where they would become applicable in surprising ways.
And second, in the majority of cases C# reasons about the types of expressions from the inside to the outside. That is, when we see x = y we analyze the types of x and y independently and then decide whether the assignment is legal. But for typeless expressions that is inverted. For x = (y)=>{whatever} we analyze the type of x, then use that to decide if (y)=>{whatever} is a legal right hand side, and if so, what type it is, and what type everything inside whatever is. That inversion of the normal order of things leads to some very complicated code in the compiler and no one was eager to add yet another case where we'd have to do inside-out reasoning.
Finally, since apparently you are interested in currying, this might be of interest to you.
http://blogs.msdn.com/b/ericlippert/archive/2009/06/25/mmm-curry.aspx
Related
I'm trying to make some method like below.
It just add two given objects and return.
object add(object a, object b);
I already tried it with dynamic keyword. Unfortunately this one does not work on iOS. (the platform does not allow runtime code generations)
dynamic add(dynamic a, dynamic b) => a + b;
So, here's my second try and I realized that it's gonna be hell with this way.
private static HybInstance Add(HybInstance a, HybInstance b)
{
if (a.Is<Int32>()) return AddInt32(a, b);
/* and so on... */
}
private static HybInstance AddInt32(HybInstance a, HybInstance b)
{
Int32 ia = a.As<Int32>();
if (b.Is<Int16>()) return HybInstance.Int(ia + b.As<Int32>());
if (b.Is<Int32>()) return HybInstance.Int(ia + b.As<Int32>());
if (b.Is<Int64>()) return HybInstance.Int64(ia + b.As<Int64>());
if (b.Is<float>()) return HybInstance.Float(ia + b.As<float>());
throw new SemanticViolationException($"");
}
// the method should support custom operators too
private static MethodInfo GetAddMethod(HybInstance left) {
return left.GetMethods("op_Addition").FirstOrDefault();
}
Is there any smarter way to add two objects?
addition:
Here are some examples what I want to do.
Just add any kind of objects or throw exception if not possible.
add(1, 1); // 2
add(1, "b"); // exception
add("a", "b"); // "ab"
// and this one also should be work
add(some_class_with_operator_overloading, 10);
Closest you could get using standard .NET types is probably IConvertible:
static IConvertible Add (IConvertible a, IConvertible b)
{
if (a is string) return a.ToString() + b;
if (b is string) return a + b.ToString();
// other special cases here
return a.ToDouble(CultureInfo.CurrentCulture) + b.ToDouble(CultureInfo.CurrentCulture);
}
static void Main(string[] args)
{
IConvertible a = 1;
IConvertible b = 2;
IConvertible s = "string";
Console.WriteLine(Add(a, b));
Console.WriteLine(Add(s, s));
Console.WriteLine(Add(a, s));
}
Produces
3
stringstring
1string
It's impossible to add two objects, because there's nothing about objects that can be added.
It's like you would like add "something" to "something" and expected someone to answer your question with precise answer - it's impossible.
object don't have any fields or properties, so how you'd like to add them??
Unless you have in mind some kind of general rule of adding objects based on their real type, then it would become possible: you would have to check the type of input parameters and then in (rather) huge switch statement return appropriate result (eg. concatenation for strings, simple addition for integers...).
Did you try with generics, 2 things though:
You are wrapping different objects in same wrapper, seems like a design issue, but will leave it since I do not know more.
Most of the int can be directly changed to Int64 and then there will not be that many special cases
I would have a generic function, and would pass it the Add/Combine function which can be defined for different types. Seems to be a cleaner approach.
public T Add<T1, T2, T>(T1 firstObject, T2 secondObject, Func<T1,T2,T>Combine)
{
var result = Combine(firstObject, secondObject);
return result;
}
Update
Seems like this will not work either
Limitations of Xamarin.iOS
No Dynamic Code Generation
Since the iOS kernel prevents an application from generating code dynamically, Xamarin.iOS does not support any form of dynamic code generation. These include:
The System.Reflection.Emit is not available.
No support for System.Runtime.Remoting.
No support for creating types dynamically (no Type.GetType ("MyType`1")), although looking up existing types (Type.GetType ("System.String") for example, works just fine).
Reverse callbacks must be registered with the runtime at compile ti
However
Why does LambdaExpression.Compile() work on iOS (Xamarin)?
On platforms that support code generation, Reflection.Emit-based
LambdaCompiler
is used.
If that's not available, the expression is interpreted using the
interpreter
For example, there are classes that interpret Constant and Add.
Original
I am not sure how much mileage you could get out of this, but you could use expressions
public static object Add<T,T2>(T a,T2 b)
{
var paramA = Expression.Parameter(typeof(T), "a");
var paramB = Expression.Parameter(typeof(T2), "b");
var body = Expression.Add(Expression.Convert(paramA, paramB.Type), paramB);
var add = Expression.Lambda<Func<T, T2, T2>>(body, paramA, paramB).Compile();
return add(a, b);
}
The assumptions it that it will try to convert to the second parameter type and return of that type.
Obviously you any class will need the appropriate operators
Given
public struct Test
{
// user-defined conversion from Fraction to double
public static implicit operator int(Test f)
{
return 10;
}
public static implicit operator Test(int i)
{
return new Test();
}
// overload operator *
public static Test operator +(Test a, Test b)
{
return new Test();
}
}
Example
Console.WriteLine(Add(1, 2));
Console.WriteLine(Add(1, 2.0));
Console.WriteLine(Add(1, new Test()));
Refelction can be used to walk the properties of both objects, check for name equivalency and numeric data type, then amend property values in a totally generic way:
public static void AddObjects(object oFrom, object oTo)
{
if (oFrom != null && oTo != null)
{
foreach (System.Reflection.PropertyInfo f in oFrom.GetType().GetProperties())
{
if ((oTo).GetType().GetProperty(f.Name) != null)
{
try
{
string sType = f.GetType().ToString().ToLower();
if (sType==("int") )
{
oFrom.GetType().GetProperty(f.Name).SetValue(oFrom, (int)(f.GetValue(oFrom)) + (int)(f.GetValue(oTo)));
}
if (sType=="int32" )
{
oFrom.GetType().GetProperty(f.Name).SetValue(oFrom, (Int32)(f.GetValue(oFrom)) + (Int32)(f.GetValue(oTo)));
}
if (sType==("int64") )
{
oFrom.GetType().GetProperty(f.Name).SetValue(oFrom, (Int64)(f.GetValue(oFrom)) + (Int64)(f.GetValue(oTo)));
}
// keep adding for all numeirc types. maybe theres a better way?
}
catch (Exception ex)
{ }
}
}
}
}
I've been looking into Functional Programming lately and wanting to bring some concepts to my C# world. I'm trying to compose functions to create services (or whatever you'd call them) instead of creating classes with injectable dependencies.
I've come up with a way to partially apply a function (to have the same effect as injecting dependencties) with two arguments and one return argument by creating a static method like this:
// this makes a func with a single arg from a func with two
static Func<T2, TResult> PartiallyApply<T1, T2, TResult>(
Func<T1,T2, TResult> f,
T1 t1)
{
// use given t1 argument to create a new function
Func<T2, TResult> map = t2 => f(t1, t2);
return map;
}
This works, however I would like to pass it a static method, like this one:
static string MakeName(string a, string b) => a + " " + b;
When I try to wire this up, I get the error The type arguments for method 'Program.PartiallyApply<T1, T2, TResult>(Func<T1, T2, TResult>, T1)' cannot be inferred from the usage. But when I add a step creating an explicit Func<string,string,string which I point to the method it does work:
static void Main(string[] args)
{
var first = "John";
var last = "Doe";
var f1 = PartiallyApply(MakeName, first); // cannot be inferred from the usage
Func<string, string, string> make = MakeName; // map it to func
var f2 = PartiallyApply(make, first); // works
var name = f2(last);
Console.WriteLine(name);
Console.ReadKey();
}
Why can't the compiler work out the type args when passing the static method directly? Is there a way where I could use static methods without the need to explicitly map them to a Func<> with essentially the same (type) arguments?
UPDATE
Reading Functional programming in C# by Enrico Buonanno (highly recommended) gives another good option for getting around this. In 7.1.3 he gives several options on how to work with Funcs directly, instead of method groups.
You could make a getter only property with a Func like this:
static Func<string, string, string> MakeName => (a,b) => a + " " + b;
Because if you has two methods with different arguments compiler don't know use method1 or method2.
example:
static string MakeName(string a, string b) => a + " " + b;
static string MakeName(int a, string b) => a + " " + b;
How could the compiler know which one you mean? Method1 or method2? Just because you only have one method in the method group now, doesn't mean it will always be that way. Adding a method would then break in this manner.
var f1 = PartiallyApply(MakeName, first);
So if you want to fix this problem you have to set your generic arguments in the method calling:
var f1 = PartiallyApply<string, string, string>(MakeName, first);
var f2 = PartiallyApply<string, int, string>(MakeName, first);
Or you can get all of arguments in your PartiallyApply method:
static string MakeName(string a, string b) => a + " " + b;
static string MakeName(int a, string b) => a + " " + b;
// this makes a func with a single arg from a func with two
static Func<T2, TResult> PartiallyApply<T1, T2, TResult>(
Func<T1, T2, TResult> f,
T1 t1,
T2 t2)
{
// use given t1 argument to create a new function
Func<T2, TResult> map = result => f(t1, t2);
return map;
}
static void Main(string[] args)
{
var first = "John";
var last = "Doe";
var f1 = PartiallyApply(MakeName, first, last); //works now
var name = f1(last);
Console.WriteLine(name);
Func<string, string, string> make = MakeName; // map it to func
var f2 = PartiallyApply(make, first, last); // works
name = f2(last);
Console.WriteLine(name);
Console.ReadKey();
}
I'm trying hard to make sense of delegates and lambda expressions and were reading through some of the questions here on stackoverflow and landed on this post where the second example in this comment got me completely lost. The first thing that confuses me is the list parameter not defined anywhere (I understand that it is the input parameter of the return type yet I find difficult to make sense of this code) but I think that everything would be much more clear by seeing how such a definition could be used in practice (and this is the second thing I'm having a hard time grasping).
How could methods such as the following be used in practice?
public Func<IList<T>, T> SelectionMethod<T>()
{
return list => list.First();
}
public Func<float, float> QuadraticFunctionMaker(float a , float b , float c)
{
return (x) => { return a * x * x + b * x + c; };
}
The parameters are defined, it's just that their types are inferred. The argument definition is the part before the => - list (inferred to be of type IList<T>) and x (inferred to be of type float) respectivelly in your examples.
The first delegate corresponds to a signature of:
T SomeMethod<T>(IList<T> list)
The second is:
float SomeMethod(float x)
Since the compiler knows what the signature of the delegate must be, it can infer the required types automatically. If you were to write out the delegate using the old-school explicit syntax, it would look something like this:
return (Func<IList<T>, T>)(delegate (IList<T> list) { return list.First(); });
If you really want to use explicit typing, you can specify the types as needed:
(IList<T> list) => list.First()
When you actually want to invoke the delegate, you need to pass the argument, e.g.:
SelectionMethod<string>()(new List<string>())
The first lambda expression is very simple. The second additionally closes over the arguments to the "creator" function, which means that you can access the arguments to the "creator" in the body of the delegate. This is entirely safe in purely immutable code, but may be tricky if you're dealing with mutable reference types and side-effects - make sure you understand the semantics properly before you do anything crazy with those.
Depending on your experience with functional programming, it might be helpful to realize that all of this is just compiler trickery. The two methods will compile to the equivalent of something like this:
public Func<IList<T>, T> SelectionMethod<T>()
{
return new Func<IList<T>, T>(__HiddenAnonymousMethod);
}
private T __HiddenAnonymousMethod<T>(IList<T> list)
{
return list.First();
}
The second example is more complicated because of the closure - we need to create a "helper object" to hold the captured locals:
private class __HiddenAnonymousClass
{
float a, b, c;
public __HiddenAnonymousClass(float a, float b, float c)
{
this.a = a; this.b = b; this.c = c;
}
public float __HiddenAnonymousMethod(float x)
{
return a * x * x + b * x + c;
}
}
public Func<float, float> QuadraticFunctionMaker(float a , float b , float c)
{
return new Func<float, float>
(new __HiddenAnonymousClass(a, b, c).__HiddenAnonymousMethod);
}
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Function overloading by return type?
Hi,
In overloading we say that the parameter list has to be different either by number or by type, but doesn't matter on the return type, Why is that so???
The function
//Function 1
int Add(int a, int b)
{return a+b;}
//Function 2
Double Add(Double a, Double b)
{return a+b;}
//Function 3
Double Add(int a, int b)
{return (Double)a+b;}
The functions 1 2 are overloaded, where as functions 1 and 3 are not ??? Reasons ???
Any help is really appreciated.
The compiler needs to know at compile time which function you are trying to call. If they differ only by return type, this is usually not possible. Consider, for example:
var result = Add(1, 2);
or
Console.WriteLine(Add(1, 2));
the compiler would not be able to know whether you want to execute function 1 or 3. And even if you did
double x = Add(1, 2);
the compiler would not know if you (a) want to call function 3 or (b) call function 1 and do an implicit widening conversion from int to double.
There are to many cases where that kind of overloading would not work. Here is two of them:
You don't care about the result of the method, and call it like this:
Add(3, 4);
Should this call method 1 or 3?
You use varto assign the result
var result = Add(3, 4);
This kind of overloading would be ambiguous at best, so therefore it's not allowed.
The other answers deal with why, but an aside: in C# you can simulate return-type based overloading by using (abusing?) implicit conversion operators (and deferring the operation):
using System;
class Program {
static void Main() {
int i = Add(3, 5); // prints: int overload called
double d = Add(3, 5); // prints: double overload called
}
static SuperMagicAdder Add(int a, int b)
{ return new SuperMagicAdder(a, b); }
}
struct SuperMagicAdder {
private readonly int a,b;
public SuperMagicAdder(int a, int b) { this.a = a; this.b = b; }
public override string ToString() { return a + "+" + b; }
public static implicit operator int (SuperMagicAdder value) {
Console.WriteLine("int overload called");
return value.a + value.b;
}
public static implicit operator double (SuperMagicAdder value) {
Console.WriteLine("double overload called");
return (double)value.a + value.b;
}
}
Note that interestingly, Anonymous Function Literals in C# are overloaded on their result type and it doesn't seem to pose any problems.
In C#, a lambda can be two very different things:
a piece of executable code (a subclass of Delegate actually)
an abstract representation of an operation (basically, an abstract syntax tree)
This is distinguished purely by the result type of the lambda literal:
Func<int, int> l = (i) => i + i * i;
is a piece of executable code. I can say
Console.WriteLine(l(3));
and I will get 12.
Expression<Func<int, int>> e = (i) => i + i * i;
is an abstract representation of that operation. I can say
Console.WriteLine(e);
and I will get
i => (i + (i * i))
Note that this is not just the original text. It really is an rendering of the abstract representation. The extra parentheses around the expression and inside it are there, because ToString() did an actual tree traversal of the AST and rendered it. The AST looks roughly like this:
And this
var v = (i) => i + i * i;
is simply illegal, because lambdas are overloaded on their result type, but the var keyword says "use the result type to figure out the type of v".
Allowing return types to be part of the signature would create major ambiguities in overload resolution.
For example, consider:
Add(2,3);
We are "throwing away" the value returned by the method, but which overload should be invoked?
It doesn't work well with implicit-typing, or with assigning the value to a variable that is compatible with either return-type. E.g.:
var sum = Add(2,3);
object sum = Add(2,3);
i am reading Accelerated C# i don't really understand the following code:
public static Func<TArg1, TResult> Bind2nd<TArg1, TArg2, TResult> (
this Func<TArg1, TArg2, TResult> func,
TArg2 constant )
{
return (x) => func( x, constant );
}
in the last line what is x referring to? and there's another:
public static Func<TArg2, Func<TArg1, TResult>> Bind2nd<TArg1, TArg2, TResult>
( this Func<TArg1, TArg2, TResult> func )
{
return (y) => (x) => func( x, y );
}
How do i evaluate this? (y) => (x) => func( x, y ) what is passed where ... it does confusing.
Let's first simplify the code:
Func<int, int> B(Func<int, int, int> f, int c)
{
return x=>f(x, c);
}
This is just the same as:
class Locals
{
public int c;
public Func<int, int, int> f;
public int Magic(int x) { return f(x, c); }
}
Func<int, int> B(Func<int, int, int> f, int c)
{
Locals locals = new Locals();
locals.f = f;
locals.c = c;
return locals.Magic;
}
Now is it clear what x refers to? x is the parameter to function "Magic".
Now you can use B like this:
Func<int, int, int> adder = (a, b)=>a+b;
Func<int, int> addTen = B(adder, 10);
int thirty = addTen(20);
Make sense? See what is happening here? We're taking a function of two parameters and "fixing" one of the parameters to a constant. So it becomes a function of one parameter.
The second example takes that one step further. Again, simplify to get rid of the cruft so that you can understand it more easily:
Func<int, Func<int, int>> B2(Func<int, int, int> f)
{
return y=>x=>f(x,y);
}
This is the same as
class Locals3
{
public int y;
public int Magic3(int x)
{
return x + this.y;
}
}
class Locals2
{
public Func<int, int, int> f;
public Func<int, int> Magic2(int y)
{
Locals3 locals = new Locals3;
locals.y = y;
return locals.Magic3;
}
}
Func<int, Func<int, int>> B2(Func<int, int, int> f)
{
Locals2 locals = new Locals2();
locals.f = f;
return locals.Magic2;
}
So you say
Func<int, int, int> adder = (a, b)=>a+b;
Func<int, Func<int, int>> makeFixedAdder = B2(adder);
Func<int, int> add10 = makeFixedAdder(10);
int thirty = add10(20);
B is a parameter fixer. B2 makes a parameter fixer for you.
However, that's not the point of B2. The point of B2 is that:
adder(20, 10);
gives the same result as
B2(adder)(20)(10)
B2 turns one function of two parameters into two functions of one parameter each.
Make sense?
x is the parameter of the lambda, it is of type TArg1.
It can be helpful to pronounce the => as "maps to" as in "x maps to a new function with a constant of type TArg2 substituted into the original function delegate, func."
The variable x is an unbound variable. That represents an argument to the returned function from calling Bind2nd.
A few hours with Scheme would help you here, but try this.
When you call Bind2nd the returned result is a function. That function is defined as
(x) => func (x, constant)
Now that you have the above assigned to a variable, lets say lambda, you can call that function via the lambda variable
lambda(x);
The x defined in Bind2nd is just a variable that represents an argument to the function that will be returned to you.
A lambda expression is shorthand for anonymous method. Like anonymous method, lambda expression is assigned to delegate types. All conditions that apply for anonymous methods also apply to lambda expressions.
=> is called lambda operator, which is read as “goes to”. The left side of the operator specifies the input parameters separated by comma, and the right side specifies an expression or statement block which is called lambda body. (p1, p2, p3, …pN) => expression If you have only one parameter then you can skip the parenthesis p1 => expression;
I have written a small blog explaining lambda expression here Lambda Expression