How to mix monadic constructs in a single Linq expression? - c#

I have a toy implementation of a Maybe monad in C# and have implemented the relevant SelectMany extension methods to work with Linq. I stumbled upon a problem when I tried to mix IEnumerable and IMaybe in a single Linq statement.
The Maybe monad looks like
public interface IMaybe<T>
{
bool HasValue { get; }
T Value { get; }
}
public static class Maybe
{
class SomeImpl<T>: IMaybe<T> // obvious implementation snipped for brevity
class NoneImpl<T>: IMaybe<T> // obvious implementation snipped for brevity
// methods to construct the Maybe monad
public static Wrap<T> Some<T>(T value);
public static Wrap<T> Some<T>(T? value) where T: struct;
public static IMaybe<T> None<T>();
public static IMaybe<B> SelectMany<A, B>(this IMaybe<A> a, Func<A, IMaybe<B>> mapFn)
{
if (a.HasValue)
return mapFn(a.Value);
else
return None<B>();
}
public static IMaybe<C> SelectMany<A, B, C>(
this IMaybe<A> a, Func<A, IMaybe<B>> mapFn, Func<A, B, C> selector)
{
if (a.HasValue)
{
var b = mapFn(a.Value);
if (b.HasValue)
return Some(selector(a.Value, b.Value));
else
return None<C>();
}
else
return None<C>();
}
}
My program tries to read a file, parse the content into a number of URI entries, and for each of the entries download the content from the URI. Exactly how these operations are implemented is irrelevant. The trouble I have lies in the chaining these operations in a Linq statement. I.e.
static IMaybe<string> ReadFile(string path);
static IMaybe<KeyValuePair<string, Uri>[]> ParseEntries(string input);
static IMaybe<string> Download(Uri location);
static void Main(string[] args)
{
var result = // IEnumerable<IMaybe<anonymous type of {Key, Content}>>
from fileContent in ReadFile(args[0])
from entries in ParseEntries(fileContent)
from entry in entries // this line won't compile
from download in Download(entry.Value)
select new { Key = entry.Key, Content = download };
// rest of program snipped off for brevity
}
The error in question complains about mixing the IMaybe and IEnumerable monads. In its exact wording:
Error 1 An expression of type 'System.Collections.Generic.KeyValuePair[]' is not allowed in a subsequent from clause in a query expression with source type 'MonadicSharp.IMaybe'. Type inference failed in the call to 'SelectMany'. C:\Dev\Local\MonadicSharp\MonadicSharp\Program.cs 142 31 MonadicSharp
How do I get around this?

It seems to me that the issue lies in the signature for ParseEntries.
It currently is:
static IMaybe<KeyValuePair<string, Uri>[]> ParseEntries(string input);
Perhaps it should be?
static IMaybe<KeyValuePair<string, Uri>>[] ParseEntries(string input);
So instead of a maybe of array it should be an array of maybe.

I think the issue is because entries is of type IMaybe<T> and not of type IEnumerable<T>.
Have you tried something like this:
from entry in entries.Value
Of course this is not what the purpose of a Monad is, but this should be the first step.

After some research I've concluded that it is just impossible to mix monads in a single LINQ statement so I decided to break it into two statements. This is how it works:
First off, I need to make a slight change to the IMaybe interface declaration to use covariance:
public interface IMaybe<out T>{ ... }
Next, I need some helper method to transform the IMaybe monad to the IEnumerable monad:
public static IEnumerable<IMaybe<T>> UnfoldAll<T>(
this IMaybe<IEnumerable<T>> source)
{
if (source.HasValue)
return Enumerable.Range(0, 1).Select(i => Maybe.None<T>());
else
return source.Value.Select(value => Maybe.Some(value));
}
And finally, I will break the original LINQ statement into two statements (nesting LINQ expressions works too)
static void Main(string[] args)
{
var path = args[0];
var theEntries =
from fileContent in ReadFile(path)
from entries in ParseEntries(fileContent)
select entries;
var theContents =
from entry in theEntries.UnfoldAll()
where entry.HasValue
select Download(entry.Value.Value);
foreach (var content in theContents)
{
//...
}
}
As you can see, the first LINQ statement works on IMaybe monad and the second one on the IEnumerable.

Related

How to cast Predicate<T> to Func<T, bool> [duplicate]

I have a class with a member Predicate which I would like to use in a Linq expression:
using System.Linq;
class MyClass
{
public bool DoAllHaveSomeProperty()
{
return m_instrumentList.All(m_filterExpression);
}
private IEnumerable<Instrument> m_instrumentList;
private Predicate<Instrument> m_filterExpression;
}
As I read that "Predicate<T> is [...] completely equivalent to Func<T, bool>" (see here), I would expect this to work, since All takes in as argument: Func<Instrument, bool> predicate.
However, I get the error:
Argument 2: cannot convert from 'System.Predicate<MyNamespace.Instrument>' to 'System.Type'
Is there a way to convert the predicate to an argument that this function will swallow?
The two types represent the same logical signature, but that doesn't mean they're just interchangable. A straight assignment won't work, for example - but you can create a new Func<T, bool> from the Predicate<T, bool>. Sample code:
Predicate<string> pred = x => x.Length > 10;
// Func<string, bool> func = pred; // Error
Func<string, bool> func = new Func<string, bool>(pred); // Okay
This is a bit like having two enum types with the same values - you can convert between them, but you have to do so explicitly. They're still separate types.
In your case, this means you could write:
public bool DoAllHaveSomeProperty()
{
return m_instrumentList.All(new Func<T, bool>(m_filterExpression));
}
The lambda expression approach suggested by other answers will work too, of course.
public bool DoAllHaveSomeProperty()
{
return m_instrumentList.All(i => m_filterExpression(i));
}
You can convert a predicate to a method by calling Invoke. All delegates have this member. Delegates don't have structural identity, but methods can be converted to matching delegates. This fix has a minor performance cost, as it adds an extra layer of indirection. However, most solutions to this problem have that problem. Eric Lippert discusses this in more detail at https://web.archive.org/web/20140625132124/http://blog.coverity.com/2014/06/18/delegates-structural-identity/ .
In your specific case, replace return m_instrumentList.All(m_filterExpression); with return m_instrumentList.All(m_filterExpression.Invoke);
Sample code demonstrating the actual problem.
void Main()
{
Predicate<int> t1 = Foo;
Func<int,bool> t2 = Foo;
Predicate<int> t3 = t2.Invoke; //Legal
Func<int,bool> t4 = t1.Invoke; //Legal
Predicate<int> t5 = t2; //Illegal
Func<int,bool> t6 = t1; //Illegal
}
bool Foo(int x)
{
return x > 20;
}
return m_instrumentList.All(i => m_filterExpression(i));
Since there are a lot of answers i will add one more just for fun.
If you want your code to compile you can use extention methods
//Original Code
class MyClass4
{
public bool DoAllHaveSomeProperty()
{
return m_instrumentList.All(m_filterExpression);
}
private IEnumerable<Instrument> m_instrumentList;
private Predicate<Instrument> m_filterExpression;
}
Add this class in the same namespace
public static class MyExtentions
{
public static bool All(this IEnumerable<Instrument> enumer, Predicate<Instrument> pred)
{
return enumer.All(e => pred(e));
}
}
As Brian said, you can convert a predicate to a method via Invoke:
public bool DoAllHaveSomeProperty()
{
return m_instrumentList.All(m_filterExpression.Invoke);
}

Force C# compiler to use non-generic method overload with Linq Expression parameter

I have overloaded methods, one generic and one non-generic. The two methods both receive a Linq Expression as single parameter:
public void Test(Expression<Action<char>> expr) {}
public void Test<T>(Expression<Func<char, T>> expr) {}
Now consider the following invocation:
var sb = new StringBuilder();
Test(c => sb.Append(c));
The compiler will pick the generic method since the Append() method does (unfortunately) return a StringBuilder. However, in my case I absolutely need the non-generic method to be called.
The following workaround shows that there is no type issue with the code (the non-generic call would be perfectly valid):
Expression<Action<char>> expr = c => sb.Append(c);
Test(expr);
However, I'd prefer not to declare a variable with an explicit type and instead somehow get the compiler to pick the non-generic method (just like I could tell it to use the generic method with explicit type parameters).
You can play with this at SharpLab.io.
This may seem like a workaround (because it is), but you can used a named parameter to clarify which method you are calling.
static public void Test(Expression<Action<char>> action)
{
Console.WriteLine("Test()");
}
static public void Test<T>(Expression<Func<char, T>> func)
{
Console.WriteLine("Test<T>()");
}
When you want the non-generic version, just provide the parameter name action: in the argument list.
static public void Main()
{
var sb = new StringBuilder();
Test(action: c => sb.Append(c) );
Test(func: c => sb.Append(c) );
}
Output:
Test()
Test<T>()
This might be easier to use than writing out the expression cast.
Fiddle
You can use an empty method to swallow the return value of sb.Append. I wouldn't call this a workaround, since it just makes the compiler work normally, but it isn't totally clean and pretty either.
static public void NoValue(object value) {}
static public void Test(Expression<Action<char>> action)
{
Console.WriteLine("Test()");
}
static public void Test<T>(Expression<Func<char, T>> func)
{
Console.WriteLine("Test<T>()");
}
When you wrap the output in NoValue, the compiler correctly sees this as an Action, not a function.
static public void Main()
{
var sb = new StringBuilder();
Test(c => NoValue(sb.Append(c)) );
Test(c => sb.Append(c) );
}
Output:
Test()
Test<T>()

How can I implement NotOfType<T> in LINQ that has a nice calling syntax?

I'm trying to come up with an implementation for NotOfType, which has a readable call syntax. NotOfType should be the complement to OfType<T> and would consequently yield all elements that are not of type T
My goal was to implement a method which would be called just like OfType<T>, like in the last line of this snippet:
public abstract class Animal {}
public class Monkey : Animal {}
public class Giraffe : Animal {}
public class Lion : Animal {}
var monkey = new Monkey();
var giraffe = new Giraffe();
var lion = new Lion();
IEnumerable<Animal> animals = new Animal[] { monkey, giraffe, lion };
IEnumerable<Animal> fewerAnimals = animals.NotOfType<Giraffe>();
However, I can not come up with an implementation that supports that specific calling syntax.
This is what I've tried so far:
public static class EnumerableExtensions
{
public static IEnumerable<T> NotOfType<T>(this IEnumerable<T> sequence, Type type)
{
return sequence.Where(x => x.GetType() != type);
}
public static IEnumerable<T> NotOfType<T, TExclude>(this IEnumerable<T> sequence)
{
return sequence.Where(x => !(x is TExclude));
}
}
Calling these methods would look like this:
// Animal is inferred
IEnumerable<Animal> fewerAnimals = animals.NotOfType(typeof(Giraffe));
and
// Not all types could be inferred, so I have to state all types explicitly
IEnumerable<Animal> fewerAnimals = animals.NotOfType<Animal, Giraffe>();
I think that there are major drawbacks with the style of both of these calls. The first one suffers from a redundant "of type/type of" construct, and the second one just doesn't make sense (do I want a list of animals that are neither Animals nor Giraffes?).
So, is there a way to accomplish what I want? If not, could it be possible in future versions of the language? (I'm thinking that maybe one day we will have named type arguments, or that we only need to explicitly supply type arguments that can't be inferred?)
Or am I just being silly?
I am not sure why you don't just say:
animals.Where(x => !(x is Giraffe));
This seems perfectly readable to me. It is certainly more straight-forward to me than animals.NotOfType<Animal, Giraffe>() which would confuse me if I came across it... the first would never confuse me since it is immediately readable.
If you wanted a fluent interface, I suppose you could also do something like this with an extension method predicate on Object:
animals.Where(x => x.NotOfType<Giraffe>())
How about
animals.NotOf(typeof(Giraffe));
Alternatively, you can split the generic parameters across two methods:
animals.NotOf().Type<Giraffe>();
public static NotOfHolder<TSource> NotOf<TSource>(this IEnumerable<TSource> source);
public class NotOfHolder<TSource> : IHideObjectMembers {
public IEnumerable<TSource> NotOf<TNot>();
}
Also, you need to decide whether to also exclude inherited types.
This might seem like a strange suggestion, but what about an extension method on plain old IEnumerable? This would mirror the signature of OfType<T>, and it would also eliminate the issue of the redundant <T, TExclude> type parameters.
I would also argue that if you have a strongly-typed sequence already, there is very little reason for a special NotOfType<T> method; it seems a lot more potentially useful (in my mind) to exclude a specific type from a sequence of arbitrary type... or let me put it this way: if you're dealing with an IEnumerable<T>, it's trivial to call Where(x => !(x is T)); the usefulness of a method like NotOfType<T> becomes more questionable in this case.
If you're going to make a method for inference, you want to infer all the way. That requires an example of each type:
public static class ExtMethods
{
public static IEnumerable<T> NotOfType<T, U>(this IEnumerable<T> source)
{
return source.Where(t => !(t is U));
}
// helper method for type inference by example
public static IEnumerable<T> NotOfSameType<T, U>(
this IEnumerable<T> source,
U example)
{
return source.NotOfType<T, U>();
}
}
called by
List<ValueType> items = new List<ValueType>() { 1, 1.0m, 1.0 };
IEnumerable<ValueType> result = items.NotOfSameType(2);
I had a similar problem, and came across this question whilst looking for an answer.
I instead settled for the following calling syntax:
var fewerAnimals = animals.Except(animals.OfType<Giraffe>());
It has the disadvantage that it enumerates the collection twice (so cannot be used with an infinite series), but the advantage that no new helper function is required, and the meaning is clear.
In my actual use case, I also ended up adding a .Where(...) after the .OfType<Giraffe>() (giraffes also included unless they meet a particular exclusion condition that only makes sense for giraffes)
I've just tried this and it works...
public static IEnumerable<TResult> NotOfType<TExclude, TResult>(this IEnumerable<TResult> sequence)
=> sequence.Where(x => !(x is TExclude));
Am I missing something?
You might consider this
public static IEnumerable NotOfType<TResult>(this IEnumerable source)
{
Type type = typeof(Type);
foreach (var item in source)
{
if (type != item.GetType())
{
yield return item;
}
}
}

Passing a Func<T, TResult> where TResult is unknown

Note: Please re-tag and/or re-name appropriately
I have a class, FooEnumerator, that wraps a Foo and implements IEnumerable<FooEnumerator>. The Foos represent a tree-like data structure, the FooEnumerators that are enumerated are the child nodes of the current node.
Foo is a vendor supplied data object. FooEnumerator implements a bunch of custom filtering code.
class FooEnumerator : IEnumerable<FooEnumerator>
{
public Foo WrappedNode { get; private set; }
public string Name { get { return WrappedNode.Name; } }
public int Id { get{ return WrappedNode.Id; } }
public DateTime Created { get{ return WrappedNode.Created; } }
public FooEnumerator(Foo wrappedNode)
{
WrappedNode = wrappedNode;
}
public IEnumerator<FooEnumerator> GetEnumerator()
{
foreach (Foo child in this.GetChildren())
if(FilteringLogicInHere(child))
yield return new FooEnumerator(child);
}
...
}
I want to be able to sort each level of the tree with a given (arbitrary) expression, defined when the top level FooEnumerator is created, and have this expression passed down to each newly enumerated item to use.
I'd like to define the sort expression using lambda's, in the same way you would with the OrderBy function. In fact, it is my intention to pass the lambda to OrderBy.
The signiture for OrderBy is
OrderBy<TSource, TKey>(Func<TSource, TKey> keySelector)
where TKey is the return type of the given Func, but is a Type Parameter in the method signature and is figured out at compile time.
Example usage
var x = GetStartingNode();
var sort = n => n.DateTime;
var enu = new FooEnumerator(x, sort);
var sort2 = n => n.Name;
var enu2 = new FooEnumerator(x, sort2);
The sort expression would then be stored in a class variable and FooEnumerator would work like:
// pseudo-implementation
private Expression<Func<Foo, TKey>> _sortBy;
public FooEnumerator(Foo wrappedNode, Expression<Func<Foo, TKey>> sortBy)
{
WrappedNode = wrappedNode;
_sortBy = sortBy;
}
public IEnumerator<FooEnumerator> GetEnumerator()
{
foreach (Foo child in this.GetChildren().OrderBy(_sortBy))
if(FilteringLogicInHere(child))
yield return new FooEnumerator(child);
}
How can I specify the type of TKey (implicitly or explicitly) in this use case?
I don't want to hard code it as I want to be able to sort on any and all properties of the underlying Foo.
Well, you can't create a member delegate variable of type Expression<Func<Foo,TKey>> since TKey is never specified. However, you could create a member of type Expression<Func<Foo,IComparable>> which may suffice for your purposes. You could need to change your FooEnumerator constructor to accept this signature as well, of course.
EDIT: Others have suggested parameterizing your FooEnumerator so that it accepts a TKey. You can certainly do this, but you should be aware of the issues that emerge:
By parameterizing the enumerator you are then kicking the bucket down the road. Any code that wants to store a FooEnumerator<T> has to have a-priori knowledge of the type T. You could, however, implement a non-generic interface IFooEnumerator to deal with that.
Parameterizing an enumerator creates issues if you want to support ordering on multiple fields in the future. C# doesn't support generics with a variable number of type parameters, which limits the creation of generics that require multiple arbitrary types. This issue is harder to deal with, since it's awkward to start creating FooEnumerator<T>, FooEnumerator<T1,T2>, FooEnumerator<T1,T2,T3...>, and so on.
You can also parameterize your Enumerator:
class FooEnumerator<TKey> {
// ... All your 'pseudo' code would work here
}
I recommend programming against the interface using IComparable however.

LINQ identity function

Just a little niggle about LINQ syntax. I'm flattening an IEnumerable<IEnumerable<T>> with SelectMany(x => x).
My problem is with the lambda expression x => x. It looks a bit ugly. Is there some static 'identity function' object that I can use instead of x => x? Something like SelectMany(IdentityFunction)?
Unless I misunderstand the question, the following seems to work fine for me in C# 4:
public static class Defines
{
public static T Identity<T>(T pValue)
{
return pValue;
}
...
You can then do the following in your example:
var result =
enumerableOfEnumerables
.SelectMany(Defines.Identity);
As well as use Defines.Identity anywhere you would use a lambda that looks like x => x.
Note: this answer was correct for C# 3, but at some point (C# 4? C# 5?) type inference improved so that the IdentityFunction method shown below can be used easily.
No, there isn't. It would have to be generic, to start with:
public static Func<T, T> IdentityFunction<T>()
{
return x => x;
}
But then type inference wouldn't work, so you'd have to do:
SelectMany(Helpers.IdentityFunction<Foo>())
which is a lot uglier than x => x.
Another possibility is that you wrap this in an extension method:
public static IEnumerable<T> Flatten<T>
(this IEnumerable<IEnumerable<T>> source)
{
return source.SelectMany(x => x);
}
Unfortunately with generic variance the way it is, that may well fall foul of various cases in C# 3... it wouldn't be applicable to List<List<string>> for example. You could make it more generic:
public static IEnumerable<TElement> Flatten<TElement, TWrapper>
(this IEnumerable<TWrapper> source) where TWrapper : IEnumerable<TElement>
{
return source.SelectMany(x => x);
}
But again, you've then got type inference problems, I suspect...
EDIT: To respond to the comments... yes, C# 4 makes this easier. Or rather, it makes the first Flatten method more useful than it is in C# 3. Here's an example which works in C# 4, but doesn't work in C# 3 because the compiler can't convert from List<List<string>> to IEnumerable<IEnumerable<string>>:
using System;
using System.Collections.Generic;
using System.Linq;
public static class Extensions
{
public static IEnumerable<T> Flatten<T>
(this IEnumerable<IEnumerable<T>> source)
{
return source.SelectMany(x => x);
}
}
class Test
{
static void Main()
{
List<List<string>> strings = new List<List<string>>
{
new List<string> { "x", "y", "z" },
new List<string> { "0", "1", "2" }
};
foreach (string x in strings.Flatten())
{
Console.WriteLine(x);
}
}
}
With C# 6.0 and if you reference FSharp.Core you can do:
using static Microsoft.FSharp.Core.Operators
And then you're free to do:
SelectMany(Identity)
With C# 6.0 things are getting better. We can define the identity function in the way suggested by #Sahuagin:
static class Functions
{
public static T It<T>(T item) => item;
}
And then use it in SelectMany the using static constructor:
using Functions;
...
var result = enumerableOfEnumerables.SelectMany(It);
I think it looks very laconic in the such way. I also find the identity function useful when building dictionaries:
class P
{
P(int id, string name) // Sad. We are not getting primary constructors in C# 6.0
{
ID = id;
Name = id;
}
int ID { get; }
int Name { get; }
static void Main(string[] args)
{
var items = new[] { new P(1, "Jack"), new P(2, "Jill"), new P(3, "Peter") };
var dict = items.ToDictionary(x => x.ID, It);
}
}
This may work in the way you want. I realize Jon posted a version of this solution, but he has a second type parameter which is only necessary if the resulting sequence type is different from the source sequence type.
public static IEnumerable<T> Flatten<T>(this IEnumerable<T> source)
where T : IEnumerable<T>
{
return source.SelectMany(item => item);
}
You can get close to what you need. Instead of a regular static function, consider an extension method for your IEnumerable<T>, as if the identity function is of the collection, not the type (a collection can generate the identity function of its items):
public static Func<T, T> IdentityFunction<T>(this IEnumerable<T> enumerable)
{
return x => x;
}
with this, you don't have to specify the type again, and write:
IEnumerable<IEnumerable<T>> deepList = ... ;
var flat = deepList.SelectMany(deepList.IdentityFunction());
This does feel a bit abusive though, and I'd probably go with x=>x. Also, you cannot use it fluently (in chaining), so it will not always be useful.
I'd go with a simple class with a single static property and add as many as required down the line
internal class IdentityFunction<TSource>
{
public static Func<TSource, TSource> Instance
{
get { return x => x; }
}
}
SelectMany(IdentityFunction<Foo>.Instance)

Categories