konto usunięte

Temat: C# 4.0 Dynamic

Jako że umarzam że dynamic w aspekcie obiektowym jest zły, to w aspekcie funkcyjnym robi na mnie wrażenie, oto kolejne podejście do funkcji Curry tym razem z użyciem dynamica (poprzednia wersja na moim blogu).



/// <summary>
/// the basic Curry function.
/// </summary>
/// <param name="num">num.</param>
/// <returns>List of System Func dynamic dynamic.</returns>
public static Func<dynamic, dynamic> Curry(int num)
{
int acc = num;

return delegate(dynamic dyn)
{
if (dyn is Func<dynamic, dynamic>)
{
return dyn(acc);
}

acc += dyn;
return acc;
};
}

/// <summary>
/// the Curry2 function that utilizes the dynamic keyword.
/// </summary>
/// <param name="num">num.</param>
/// <returns>List of System Func dynamic dynamic.</returns>
public static Func<dynamic, dynamic> Curry2(int num)
{
int acc = num;

return delegate(dynamic dyn)
{
if (dyn is bool)
{
return acc;
}

acc += dyn;
return new Func<dynamic, dynamic>(Curry2(acc));
};
}



kod jest dość prosty, i jak widać jest tu dużo miejsca na poprawki, lecz ważniejsza jest tu istota co z tym można zrobić, oto przykład.



Func<dynamic,dynamic> fun1 = Program.Curry(1);
Func<dynamic,dynamic> fun2 = Program.Curry(2);
var res = Program.Curry(3)(fun1(fun2)); //6
var result = Program.Curry2(1)(2)(4)(5)(10)(false); //22

Func<dynamic, dynamic> fun3 = Program.Curry2(1)(2);
var result2 = fun3(1)(5)(false); //9

Console.ReadKey();



Jak widać nasza funkcja zwraca nowy delegat do samej siebie, chyba że parametrem będzie bool wtedy nasz curry accumulator, przerywa sumowanie i podaje wynik, po wprowadzeniu dynamica oraz lambd możliwym stało się zaimplementowanie całego rachunku lambdy.

Więc operatory jak S,K,Y oraz T i F są możliwe do zaimplementowania w C#.

Edit: pozwoliłem sobie rozszerzyć temat o kolejne przykłady, tekst można znaleźć tutaj: http://badamczewski.blogspot.com/2010/04/c-dynamic.htmlBartosz Adamczewski edytował(a) ten post dnia 30.04.10 o godzinie 16:02
Stanisław P.

Stanisław P. Software designer

Temat: C# 4.0 Dynamic

Bartosz Adamczewski:
Więc operatory jak S,K,Y oraz T i F są możliwe do zaimplementowania w C#.
Czy aby na pewno? Na przykład biorąc Y... Wiadomo - można zrobić Y: f, ... -> f(f, ...), ale musiałaby być osobna funkcja dla f(f, x), f(f, x, y), f(f, x, y, z), itd. Oczywiście zlikwidowany został problem rekursywnego Func<Func<AAAAAA!>,object,object>, ale dalej tak koślawo to wygląda trochę.

Ale dalej można zrobić nawet poprawnie typowany Y bez dynamic'a!
static Func<T,T> Y<T>(Func<object,T,T> f) {
return (x) => f(f, x);
}

static void Main(String[] args) {
var x = Y<int>( (f, n) => ( n>0 ? n+((Func<object, int, int>)f) (f, n-1) : 0));
System.Console.WriteLine(x(3));
}

Niestety bez tego jednego cast'a F'a się nie obejdzie... Bo: "cannot convert `System.Func<S,T,T>' expression to type `S'"Stanisław Pitucha edytował(a) ten post dnia 02.05.10 o godzinie 03:57

konto usunięte

Temat: C# 4.0 Dynamic

Tak na pewno :-). Oczywiście masz racje co do faktu ze dla Y trzeba zrobić osobną funkcje i ją zagnieżdżać, ale nie zmienia to faktu ze jest to możliwe bez casta.



Func<Func<dynamic, dynamic>, dynamic> fx = x => x;
var Y = fx(f => fx(x => f(fx(y => x(x)(y))))(fx(x => f(fx(y => x(x)(y))))));



Taka implementacja kombinatora dobrze odzwierciedla teorię:

Y = λf·(λx·f (x x)) (λx·f (x x))

Jako że jesteśmy w temacie teorii rachunku lambda to:

http://pl.wikipedia.org/wiki/Rachunek_lambda

Jeśli się mylę to niech mnie ktoś poprawi ale zdaje się że funkcje
AND oraz OR są błędnie zdefiniowane.

czy nie powinno być?

AND := λx.λy.x y x
OR := λx.λy.x x yBartosz Adamczewski edytował(a) ten post dnia 02.05.10 o godzinie 14:18

Następna dyskusja:

dynamic w 4.0 - wcale nie t...




Wyślij zaproszenie do