Hello i am trying to implement my own higher-order extensions but i can not understand why the aggregate (fold) gives the following error :
Error:
Cannot convert lambda expression to intended delegate
type because some of
the< return types in the block are not implicitly convertible to the delegate
return type.
I do not understand why it says the return types don't match.I use as a seed
a List<object>
and in the Fold
for every element i add the element to the list and return the List<Object>
.
Extension class:
public static class HOrder
{
public static IEnumerable<U> Map<T,U>(this IEnumerable<T> collection, Func<T, U> transform)
{
var map = collection.Select(transform);
return map;
}
public static TAccumulate Fold<TAccumulate,TSource>(this IEnumerable<TSource>source,TAccumulate seed,Func<TAccumulate,TSource,TAccumulate>aggregate)
{
var fold = Enumerable.Aggregate(source, seed, aggregate);
return fold;
}
internal static object Extractor(Node node)
{
object result;
switch (node.Kind)
{
case Node.Discriminator.String: result = node.AsStirng.Value; break;
case Node.Discriminator.Integer: result = node.AsInteger.Value; break;
case Node.Discriminator.Array: result =
HOrder.Fold<Node,List<object>>(
node.AsArray.Items,
new List<object>(),
(x, y) => { y.Add(Extractor(x)); return y; } //<--Error at return y
);
break;
default:throw new NotImplementedException();
}
return result;
}
}
P.S : The error is highlighted on the return y
.
T
==Y
thenList<T>== List<Y>
.The type isList<object>
and i am not doing any type inference.It is crystal clear the signature. I just use a side-effect to add an item to an already existing list.Node
type in order to reproduce this for ourselves. Could you either includeNode
or reduce the problem to something smaller using system types?(x, y) =>
to(y, x) =>
and it should work. One reason why single letter variable names suck sometimes. Though... I'm surprised you weren't getting errors for the Add/Extractor calls. Actually... You have them reversed in your call to Fold<> as well. It should beFold<List<object>, Node>
since accumulate comes first and source secondSelect
andAggregate
LINQ functions?HOrder.Fold(node.AsArray.Items, new List<object>(), (x, y) => { x.Add(Extractor(y)); return x; });
though I see no benefit of using this over Aggregate directly. What's more, since you've defined these as extensions, you can call them as such:node.AsArray.Items.Fold(new List<object>(), (x, y) => { x.Add(Extractor(y)); return x; });