Is there any way that I can generalise the type definitions here?
Ideally, I'd like to be able to change the type of 'testInput' and have test correctly infer the type at compile time.
public static void Run()
{
var testInput = 3;
var test = ((Func<int, int>) Identity).Compose<int,int,int>(n => n)(testInput);
Console.WriteLine(test);
}
public static Func<T, V> Compose<T, U, V>(this Func<U, V> f, Func<T, U> g)
{
return x => f(g(x));
}
public static T Identity<T> (this T value)
{
return value;
}
Update:
I can specify the type of the function passed into Compose but this still specifies the type in the line.
public static void Run()
{
var testInput = 3;
var identity = (Func<int, int>) Identity;
var test = identity.Compose((int n) => n)(testInput);
Console.WriteLine(test);
}
A little context; I'm working through Wes Dyer's The Marvel of Monads
Well seeing as I'm on a roll for spewing out text tonight I'll have my own stab at it. I should note that I am no expert on the C# compiler, I haven't read the specification (any of them... for anything), and although that article you linked was really interesting, I'd be lying if I said I was any sort of expert on that either (or even understood it all 100%).
Caveats aside, my take on your question is this:
Is there any way that I can generalise
the type definitions here?
I think the short answer is no. With the information provided, there is simply not enough information for the type inference part of C#'s compiler to infer enough information from the usage of the various variables.
As the other answers here demonstrate, it can be simplified. You can use #Lee's IdentityFunc to allow for type inference with var identity. However, even with this addition, it is still not possible with your sample code to infer all the type variables of Compose.
Imagine the following situation:
public static Func<T, V> Compose<T, U, V>(this Func<U, V> f, Func<T, U> g)
{
return x => f(g(x));
}
public static T Identity<T> (this T value)
{
return value;
}
public static Func<T, T> IdentityFunc<T>(this T value)
{
return (Func<T, T>)Identity;
}
and
public static void Run()
{
var a = 3; // a is int
var i = a.IdentityFunc(); // i is Func<int, int>;
var test = i.Compose(n => n)(a) // test is expected to be int
}
Initially this might appear as if test should easily be inferred to int. However, the return type of i.Compose can only be inferred after the fact, from its usage. The C# compiler obviously won't allow this.
public static void Run()
{
var a = 3; // a is int
var i = a.IdentityFunc(); // i is Func<int, int>;
var c = i.Compose(n => n) // c is Func<T, int> - T cannot be resolved without knowledge of n
var test = c(a); // ideally have type inference infer c (Func<T, int>) as Func<int, int>
}
In that example, upon usage of c with a the compiler would have to retrospectively infer the return type of the call to i.Compose<T, U, V>(n => n) to be Func<int, int>. This is obviously not possible in the C# compiler. Take away the call c(a) and the compiler would have no knowledge of the usage of c, which would remove any possibility of inferring T (not that it can anyway). It is possible a more advanced type inference system would be able to do this sort of inferring based on the usage of a generic return (possibly F# - another topic I'm no expert on).
As Wes Dyer doesn't provide specific usage of that particular example, it's unknown whether there is some other magic he uses to allow for the degree of type inference you're trying to achieve.
More qualified people like Eric Lippert would be able to provide you with a much greater level of detail (and technical accuracy / acuity). I read a great response he wrote on here to a question on type inference, but I can't find it. His blog has lots of great information. You could try contacting him if you're interested. Also, his answer to this question here discusses monads (and ultimately links back to Wes Dyer's article) buy you might be interested in reading it: Monad in plain English? (For the OOP programmer with no FP background)
You could write an extension method to return the Identity function for a type:
public static Func<T, T> IdentityFunc<T>(this T value)
{
return (Func<T, T>)Identity;
}
(or just return v => value;)
Your test then becomes
var testInput = 3;
var identity = testInput.IdentityFunc();
test = identity.Compose((int n) => n)(testInput);
The closest I can get is to explicitly type the parameter for the n => n lambda:
var test = ((Func<int, int>)Identity).Compose((int n) => n)(testInput);
I don't think you can achieve your ideal; C# type inference does not work like that.
You might enjoy F#.
Related
I am trying to make an extension method more generic to avoid redundancy (Here is an example of some real code, the code below is just to demonstrate the issue - I had the idea to make the method available for IQueryable<T> as well).
The following works fine:
public static class Extensions
{
public static IEnumerable<T> MySelect1<T, V>(this IEnumerable<T> query, Func<T, V> f)
{
// do something, then return IEnumerable<T>
var result=query.AsEnumerable<T>();
return result;
}
public static IQueryable<T> MySelect1<T, V>(this IQueryable<T> query, Func<T, V> f)
{
// do something, then return IQueryable<T>
var result = query.AsQueryable<T>();
return result;
}
}
I can use it in LinqPad like (when connected with the Northwind sample database):
var myQuery=(from x in Customers select x);
myQuery.AsEnumerable().MySelect1(d => d.CustomerID).Dump();
myQuery.AsQueryable().MySelect1(d => d.CustomerID).Dump();
Now I wanted to get rid of the duplicate implementation of MySelect1, so I refactored it as:
public static class Extensions
{
public static E MySelect2<E, T, V>(this E query, Func<T, V> f)
where E : System.Linq.IQueryable<T>, System.Collections.Generic.IEnumerable<T>
{
return (E)query.Select(f);
}
}
This compiles too, but I cannot use MySelect2 the same way as I did above, consider the following:
// CS0411 The type arguments for method 'Extensions.MySelect2<E, T, V>(E, Func<T, V>)'
// cannot be inferred from the usage. Try specifying the type arguments explicitly.
myQuery.AsEnumerable().MySelect2(d => d.CustomerID).Dump();
myQuery.AsQueryable().MySelect2(d => d.CustomerID).Dump();
Ok, doing what the error asks for works for this code line:
myQuery.AsQueryable()
.MySelect2<IQueryable<Customers>, Customers, String>(d => d.CustomerID).Dump();
but not for that one:
myQuery.AsEnumerable<Customers>()
.MySelect2<IEnumerable<Customers>, Customers, String>(d => d.CustomerID).Dump();
Here, I am getting
CS0311 The type 'System.Collections.Generic.IEnumerable<LINQPad.User.Customers>' cannot be used as type parameter 'E' in the generic type or method 'Extensions.MySelect2<E, T, V>(E, Func<T, V>)'. There is no implicit reference conversion from 'System.Collections.Generic.IEnumerable<LINQPad.User.Customers>' to 'System.Linq.IQueryable<LINQPad.User.Customers>'.
Why? And how can it be fixed? Please help.
Why?
For exactly the reason stated in the error message: you're trying to use IEnumerable<Customers> as the type argument for E, but E has this constraint:
where E : System.Linq.IQueryable<T>
And how can it be fixed?
It can't, assuming I understand what you're trying to achieve.
There's a fundamental problem with the "simplification" you're trying to achieve: you don't actually have full duplication in your original MySelect1 methods. The first calls AsEnumerable() and the second calls AsQueryable(). You're trying to replace those with a cast, and that's just not going to work.
There's a further problem, even with your original methods: you're accepting Func<T, V> f as a parameter for your queryable-based method, which means any time you call Select or similar and passing in f, you'll be calling Enumerable.Select instead of Queryable.Select. To really use IQueryable<> properly, you should accept Expression<Func<T, V>> f instead. At that point, you won't need to call AsQueryable anyway.
Your two methods "should" take radically different paths based on whether you're using LINQ to Objects or a different LINQ provider (e.g. LINQ to SQL), and that can't be hidden as a pure implementation detail without significant changes that would probably make it less useful than you want anyway.
I have been working on allowing function chaining. I have created a class called continuationmonad which takes a value, and a function from a => b. This allows me to use fmap and bind to chain these together. I have also used lazy to allowed calls to be defered where possible.
Is this class really the continuation monad or is it something else. I am finding it hard to find good literature which is not is Haskell.
Also any comments on how to improve / correct this.
using NUnit.Framework;
using System;
namespace Monads
{
public class Continuation<Input, Output>{
public Continuation(Input value, Func<Input,Output> function){
this.value = new Lazy<Input>( () => value);
this.function = function;
}
public Continuation(Lazy<Input> value, Func<Input,Output> function){
this.value = value;
this.function = function;
}
public Continuation<Output, Result> FMap<Result>(Func<Output, Result> map){
return new Continuation<Output, Result>(new Lazy<Output>( () => Run() ), x => map(x));
}
public Continuation<Output,Result> Bind<Result>(Func<Output, Continuation<Output, Result>> f){
return f(Run());
}
public Output Run(){
return function(value.Value);
}
private Func<Input, Output> function;
private Lazy<Input> value;
}
public static class ContinuationExtension{
public static Continuation<A,B> Unit<A,B>(this Func<A,B> f, A value){
return new Continuation<A, B>(value,f);
}
public static Continuation<A,B> Unit<A,B>(this A value,Func<A,B> f){
return new Continuation<A, B>(value,f);
}
}
[TestFixture]
public class MonadTests
{
public Continuation<int,int> Wrapped(int value){
return new Continuation<int,int>(value, x => x * 10);
}
[Test]
public void ContinuationMonadTests()
{
var number = 42;
var result = number.Unit(x => x + 8).FMap(x => x * 2).Bind(Wrapped).Run();
Console.WriteLine(result);
}
}
}
This is not the continuation monad. You are much closer to the Haskell Monad instance for functions.
You aren't getting anything that you couldn't get just from using Lazy<>. Since you have provided the input when you build an instance of your class, you aren't building functions, you are building values that are determined by a computation that hasn't been evaluated yet. Lazy<> delays the evaluation of computation until the value is needed.
Let's put together something like the Haskell Monad instance for functions in c#. LINQ syntax has established the convention for Monads in c#. They should have:
a Select extension method analogous to a Haskell Functor's fmap
a SelectMany extension method analogous to Haskell's Monad's >>=
an additional SelectMany that LINQ syntax uses. This takes an additional function that combines the value from two steps together.
Unfortunately, there's no convention for what the analog of a Monad's return should be called; we'll call ours Constant. Unfortunately, Constant won't be very convenient because c#'s type inference won't be able to figure out the types.
public static class Function
{
public static Func<TIn, TOut> Constant<TIn, TOut>(TOut result)
{
return x => result;
}
public static Func<TIn, TOut> Select<TIn, TMid, TOut>(
this Func<TIn, TMid> func,
Func<TMid, TOut> proj)
{
return x => proj(func(x));
}
public static Func<TIn, TOut> SelectMany<TIn, TMid, TOut>(
this Func<TIn, TMid> func,
Func<TMid, Func<TIn, TOut>> proj)
{
return x => proj(func(x))(x);
}
public static Func<TIn, TOut> SelectMany<TIn, TMid1, TMid2, TOut>(
this Func<TIn, TMid1> func,
Func<TMid1, Func<TIn, TMid2>> proj1,
Func<TMid1, TMid2, TOut> proj2)
{
return x => {
var mid1 = func(x);
var mid2 = proj1(mid1)(x);
return proj2(mid1, mid2);
};
}
}
Note that defining these extension methods only lets you interact with something like it's a Monad, it doesn't let you write code that's generic over the specific Monad being used. There's a sketch of how to do that in the second half of this answer.
This might be a bit opinion based but I'll try to give you my 5ct anyway.
Let's have a look at your class and their instances:
It includes a value and a function where you (tried) to make it all a lazy.
From a theoretical view I can see no difference to Lazy<T> on first glance:
You can surely convert one of your Continuation<Input,Output> to just a Lazy<Output>.
The same is true for the reverse: given some lazy value a you can make a instance with just
new Continuation(a, x => x)
So to me it seems that you just reinvented Lazy (which is an monad, in Haskell you would call it Identity.
The Cont monad is not really easy to crasp but it's really more related to .net-Events or .net-Observables. The datastructure itself would be like
Func<Func<Input,Output>, Output>
Where you pass in a continuation Func<Input,Output> to some internal calculation and then the struture than will call it when it has calculated an input Input to get the final result.
This might be a bit cryptic but one .net application are the Async workflows F# uses and which stood model for C#s async/await behaviour in some sense.
I have some material I used for a talk on a simpified version of this monad in C# on github maybe you'll find it interesting.
I have created a very comprehensive introduction to the Continuation monad that you can Find Here Discovering the Continuation Monad in C#
Also you can find a.Net Fiddle here
I Repeat it in summary here
Starting from an initial Function
int Square(int x ){return (x * x);}
Use Callback and remove return type
public static void Square(int x, Action<int> callback)
{
callback(x * x);
}
Curry the Callback
public static Action<Action<int>> Square(int x)
{
return (callback) => { callback(x * x); };
}
Generalize the returned Continuation
public static Func<Func<int,T>,T> Square<T>(int x)
{
return (callback) => { callback(x * x); };
}
Extract the Continuation Structure Also Known As the Return Method of the monad. That is Give me a value and i will give you a Monad for this value
//((U→ T) → T)
delegate T Cont<U, T>(Func<U, T> f);
public static Cont<U, T> ToContinuation<U, T>(this U x)
{
return (callback) => callback(x);
}
square.ToContinuation<Func<int, int>, int>()
Add The bind Monadic method and thus Complete the Monad.That is Give me a Two Monads and i will combine them to a new monad
((A→ T) → T)→( A→((B→ T) → T))→ ((B→ T) → T)
public static Cont<V, Answer> Bind<T, U, V, Answer>(
this Cont<T, Answer> m,
Func<T, Cont<U, Answer>> k,
Func<T, U, V> selector)
{
return (Func<V, Answer> c) =>
m(t => k(t)(y => c(selector(t, y))));
}
I have class X that implements an interface IX. I also have a repository class dedicated for X, which uses lambda expresions as parameters:
public interface IX
{
}
public class X : IX
{
....
}
public class XRepository : IRepository<X>
{
public IEnumerable<X> Filter(Func<X, bool> filterFunc)
{
...
}
}
I need to make the repository class work with the interface IX, therefore I add IRepository<IX> to the interfaces being implemented:
public class XRepository : IRepository<X>, IRepository<IX>
{
public IEnumerable<X> Filter(Func<X, bool> filterFunc)
{
...
}
public IEnumerable<IX> Filter(Func<IX, bool> filterFunc)
{
// I need to call the same filter method as above, but
// in order to do so I must convert the Func<IX, bool> to Func<X, bool>.
}
}
I must convert the Func<IX, bool> to Func<X, bool>, but since the code is written in C# 3.0 using .NET 3.5, I cannot benefit from Type covariance, which was introduced in 4.0.
A simple solution could be to use Func<X, bool> newFunc = x => filterFunc(x);, where filterFunc is of type Func<IX, bool>. This would compile and one might expect it to run fine, but I assume it will not. The problem is that I am using 3rd party framework for the filter implementation, namely FluentNhibernate. I know it uses expression trees to strip the passed into the lambda expression member access condition (like x => x.Name == "John") in order to build native SQL query (like WHERE Name = 'John'). The above solution would produce a Func<X, bool> that is not such expression and I fear it will fail to translate. So I need to create the same lambda expression but with the compatible type. Knowing that X implements IX, it is obvious that any code inside a Func<IX, bool> will work for objects of type X. It is not obvious for me, however, how can I perform this conversion.
I assume this can be done using expression trees. I also fear my performance will suffer greatly. Even if I decide to have another solution to my scenario, I will still appreciate the suggested way to translate one lambda into a similar another.
Edit:
To clarify more about the issue I am experiencing, I wrote the following test, simulating the real-life scenarion I am facing:
Func<IX, bool> filter = y => y.Name == "John";
Func<X, bool> compatibleFilter = y => filter(y);
...
// Inside the Filter(Func<X, bool> filter method)
using(var session = nhibernateSessionFactory.OpenSession())
{
IEnumerable<X> xx = session.Query<X>().Where(z => compatibleFilter(z)).ToList();
}
so, at the ToList() method I receive the following exception
Unable to cast object of type 'NHibernate.Hql.Ast.HqlParameter' to type 'NHibernate.Hql.Ast.HqlBooleanExpression'.
This confirms my assumption that Flunet NHiberante cannot correctly handle the compatibleFilter argument.
So what I want is a way to convert the Func to Func or as suggested by John Skeet, an Expression<Func<IX, bool>> to an Expression<Func<X, bool>> which have the same body (y => y.Name = "John").
Edit 2:
Finally I made it happen! The correct way is not to use Func<X, bool>, but Expression<Func<X, bool>>.
Expression<Func<IX, bool>> filter = y => y.Name == "John Skeet";
Expression<Func<X, bool>> compatibleFilter = Expression.Lambda<Func<X, bool>>(
filter.Body,
filter.Parameters);
This produces the correct SQL query.IX, bool
A simple solution could be to use Func<X, bool> newFunc = x => filterFunc(x); where filterFunc is of type Func<IX, bool>. This would compile and one might expect it to run fine, but I assume it will not.
Why assume, when you can test? It should work absolutely fine. After all, you're passing an argument of type X for a parameter of type IX, which causes no type safety concerns.
You'll then need to convert from IEnumerable<X> to IEnumerable<IX>, which can be done with Cast for instance:
public IEnumerable<IX> Filter(Func<IX, bool> filterFunc)
{
Func<X, bool> newFilter = x => filterFunc(x);
return Filter(newFilter).Cast<IX>();
}
why do you use your concrete type isnt IX enough:
public class IXRepository : IRepository<IX>
{
public IEnumerable<X> Filter(Func<IX, bool> filterFunc)
{
...
}
}
As i understand it correctly, covariance is a language feature. So it does not depend directly on .net 4.
I'm writing a simple proof of concept for what should be, in essence, a parser generator.
Basically I'm looking for a way that I can write a function that will return a function that converts from a string to some object of a given type - I want to be able to do the following in essence:
Func<string, double> ConvertToDouble = BuildConverter(typeof(0.0));
Obviously this is a pretty contrived example - but if I can do the simple version then I ought to be able to do the more complicated version!
FWIW, what I'm ultimately trying to do is to map a string of values onto a class, but to make it as flexible as possible, I want to do it by having a function that will return a function that does the conversion. In functional terms, I think I want something that looks like this:
a -> (string -> a)
As a first try, I've tried doing this:
public static Func<string, T> BuildParser<T>(T t)
{
if (t is String)
return new Func<string, T>(x => x.ToString());
if (t is double)
return new Func<string, T>(x => double.Parse(x));
}
Which doesn't work at all, but it leaves me feeling a bit stuck as to what approach I ought to be taking - so any help at all would be greatly appreciated!
You cannot mix class with struct types. Beyond that, it will work.
See the code below:
private void Testing() {
var func = BuildParserStruct<double>();
double value = func("5");
}
public static Func<string, T> BuildParserClass<T>() where T : class
{
return x => x as T;
}
public static Func<string, T> BuildParserStruct<T>() where T : struct
{
return (x => (T)Convert.ChangeType(x, typeof(double)));
}
I'm guessing that you want specific behaviors verified at compile time. Why not just call Convert or write individual methods to use? All that your if statements accomplish is to take role of the programmer who should be chosing the appropriate conversion method.
If you want behaviors chosen at runtime, you should return Func<string, object>, and make the method non-generic.
The issue with using a generic Type T in the method is that T is fixed for each call to the method, and the logic in the method supposes T to vary in a single call (in one case T is a string, in another case T is a decimal). The compiler cannot sort this out - it would need to allow both returnable instances to have the same type.
I'm not certain of exactly what you're trying to do, but would something like this help?
var stringParser = GetParser<string>();
string s = stringParser("test");
var doubleParser = GetParser<double>();
double d = doubleParser("42");
// ...
public static Func<string, T> GetParser<T>()
{
return (Func<string, T>)_parserCache[typeof(T)];
}
private static readonly Dictionary<Type, Delegate> _parserCache =
new Dictionary<Type, Delegate>
{
{ typeof(string), new Func<string, string>(x => x) },
{ typeof(double), new Func<string, double>(x => double.Parse(x)) }
// etc
};
ADO.Net has an Execute Scalar function that always bothered me because it returns an object. You can write a generic wrapper function to return the appropriate type. Of course this assumes that you know what type will be returned.
Somewhat simplified:
public T ExecuteScalar<T>()
{
return (T)Command.ExecuteScalar();
}
I tried to apply operators on Generics (for my example ,multiplication)
public static List<TOutput> Conversion<TOutput>(List<TInput> input)
{
List<TOutput> outList = new List<TOutput>();
foreach(TInput tinput in input)
{
double dbl = tinput *tinput;
outList.Add(dbl);
}
return outList;
}
Any workaround for fixing it?
Not possible without reflecting upon the type. There is some code that does this available as part of MiscUtil.
This is now possible in C# 11 / .NET 7 (or above):
public static List<TOutput> Conversion<TInput, TOutput>(List<TInput> input)
where TInput : IMultiplyOperators<TInput, TInput, TOutput>
{
List<TOutput> outList = new List<TOutput>();
foreach (TInput tinput in input)
{
TOutput product = tinput * tinput;
outList.Add(product);
}
return outList;
}
The compiler shouldn't allow you to assign a double to an unknown type:
outList.Add(dbl);
For all it knows, you could be trying to assign a dbl to a type of FluxCapacitor. Your code is trying to accomplish two incompatible things: to return a list of generic (unknown) type, and 2) to force that type to be a double. This doesn't make sense, which is why you're having difficulty. You can use reflection (as Porges pointed out with an excellent link) to solve this dynamically, but you really need to ask yourself: why are you trying to assign a floating point number to a class that has an unknown type? The calling code could be asking for a result of List<bool>. How much sense would it make to try to assign
double foo = 1.5;
bool bar = foo;
? Zero. You can make the compiler do anything with enough somersaults, but you need to reevaluate the purpose of your routine, why you're trying to put a specific datatype into a generic one, and whether or not this routine needs to return a generic list.
The "MiscUtil" answer (already accepted) would be my first choice ;-p
You might also consider LINQ at the caller:
var prodList = originalList.Select(x=>x*x).ToList();
Since the caller knows the type (assuming it isn't itself generic, this should work.
Just for completeness, another option here (in 4.0) is dynamic:
public static List<TOutput> Conversion<TOutput>(List<TInput> input)
{
List<TOutput> outList = new List<TOutput>();
foreach(TInput tinput in input)
{
TOutput square = (dynamic)tinput * (dynamic)tinput;
outList.Add(square);
}
return outList;
}
You could use a cached lambda to do your calculation (and/or conversion).
This doesn't require the DLR or the dynamic keyword, so it's perfectly usable in C# 3.0
static class Squarer<T>
{
private static readonly Func<T, T> _square;
static Squarer()
{
ParameterExpression x = Expression.Parameter(typeof(T), "x");
_square = Expression.Lambda<Func<T, T>>(
Expression.Multiply(x, x),
x).Compile();
}
public static T Square(T value)
{
return _square.Invoke(value);
}
}
Console.WriteLine(Squarer<double>.Square(1234.5678));
Console.WriteLine(Squarer<decimal>.Square(1234.5678m));
Console.WriteLine(Squarer<int>.Square(1234));