Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mixing extension methods, generics and lambda expressions

Tags:

c#

lambda

haskell

I'm porting Haskell's/LiveScript each function to C# and I'm having some troubles. The signature of this function is (a → Undefined) → [a] → [a] and I work very well with typing and lambda expressions in Haskell or LS, but C# makes me confused. The final use of this extension method should be:

String[] str = { "Haskell", "Scheme", "Perl", "Clojure", "LiveScript", "Erlang" };
str.Each((x) => Console.WriteLine(x));

And, with this, My output should be:

Haskell
Scheme
Perl
Clojure
LiveScript
Erlang

My current own implementation of each is:

public static void Each<T>(this IEnumberable<T> list, Action closure)
{
  foreach (var result in list)
  {
    Delegate d = closure;
    object[] parameters = { result };
    d.DynamicInvoke(parameters);
  }
}

The problem is that here I just can't pass a parameter in my lambda expression. I can't do (x) => ....

How can I pass parameters to lambda expression? It was very easier to work with first-class-functions in Haskell than in C#. I'm just very confused.

For that who don't know Each's implementation, it is used for side-effects, returns the own list and applies a closure iterating and passing each value of the list as an argument. Its implementation in PHP should be:

public static function each($func) {
  // where $this->value is a list
  foreach ($this->value as $xs) {
    $func($xs);
  }
  return $this->value;
  // Or return $this; in case of method-chaining
}

Can somebody help me? I searched for it but it isn't clear for me. [And I don't wish use Linq]

like image 282
Marcelo Camargo Avatar asked Oct 17 '14 19:10

Marcelo Camargo


1 Answers

You need an Action<T> instead of an Action. You can also invoke it directly instead of using DynamicInvoke:

public static void Each<T>(this IEnumberable<T> list, Action<T> a)
{
  foreach (var result in list)
  {
    a(result);
  }
}
like image 89
Lee Avatar answered Nov 15 '22 06:11

Lee