Sep. 19th, 2009

wizzard: (Default)

Вчера после разнообразных бредодискуссий мне внезапно вспомнилось вот это: Multi-Dimensional Analog Literals

(Для тех, кто не понял, что это такое и зачем оно:
каждая такая штука это выражение. после его вычисления получается обьект со свойствами Width, Height и Depth, соответствующими реальным размерам обьекта в коде :))

Где-то 15 минут втыкания на темплейты, “блин, я их не понимаю. и еще, а почему в C# нет темплейтов?” –> хм, стоп, а зачем нам здесь вообще темплейты?

Линейный литерал получился достаточно тривиальным, жаль, что не с таким красивым синтаксисом, плоский – тоже достаточно быстро. С трехмерным пришлось помучиться. Но не прошло и 4 часов, как на свет явилось


чудовище )

Сам класс:


чудовище 2 ) На умножение и деление меня, правда, не хватило. Но их, вроде, достаточно тривиально дописать…
wizzard: (Default)

Никогда не возникало желания добавить в C# свой оператор? Или добавить бинарный оператор над встроенными типами, например…
Идея не нова, синтаксис подсмотрен в Хаскеле. И достаточно много boilerplate code. Но как DSL – вроде красиво.

Надо подумать, что с этим можно сделать и как можно более красиво конвертировать ф-и в операторы.

Использование:

private static void ArithmeticExample()
{
Func<int, int, int> _sum = (a, b) => a + b;
Func<int, int, int> _mult = (a, b) => a * b;
var sum = _sum.Infixize();
var mult = _mult.Infixize();




Console.WriteLine(1 |sum| (2 |mult| 4) |sum| 8); //17
}

private static void PoorMansLINQ()
{
Predicate<int> odd = x => x % 2 != 0;
// why the type inference is unable to do this?
Func<IEnumerable<int>, Predicate<int>, IEnumerable<int>> _where = Where;
var where = _where.Infixize();
Func<IEnumerable<int>, Func<int, int>, IEnumerable<int>> _Map = Map;
var perform = _Map.Infixize();
Func<IEnumerable<int>, IEnumerable<int>, IEnumerable<int>> _Join = Join;
var join = _Join.Infixize();
Func<IEnumerable<int>, IEnumerable<int>, IEnumerable<int>> _Intersect = Intersect;
var intersect = _Intersect.Infixize();



foreach (var x in Enumerable.Range(0, 10)
|where| odd |perform| SideEffectPrint) ; // 1 3 5 7 9

Console.WriteLine();

foreach (var x in
Enumerable.Range(0, 5) |join| Enumerable.Range(10, 5) |intersect| Enumerable.Range(3,10)
|perform| SideEffectPrint) ; //3 4 10 11 12

Console.ReadLine();
}


Реализация:



public static class InfixExtensions
{
public static InfixOperator<T1, T2, RT> Infixize<T1,T2,RT>(this Func<T1, T2, RT> f)
{
return new InfixOperator<T1, T2, RT>(f);
}
}
/// <summary>
/// TODO: Curryable Infix Operator
/// </summary>
/// <typeparam name="T1">Left operand type</typeparam>
/// <typeparam name="T2">Right operand type</typeparam>
/// <typeparam name="RT">Return type</typeparam>
public class InfixOperator<T1,T2,RT>
{
Func<T1, T2, RT> function;
T1 leftvalue;
public InfixOperator(Func<T1,T2,RT> f)
{
this.function = f;
}
public InfixOperator(T1 lv, Func<T1, T2, RT> f)
{
this.function = f;
this.leftvalue = lv;
}
public static RT operator |(InfixOperator<T1,T2,RT> a, T2 b)
{
return a.function(a.leftvalue, b);
}
public static InfixOperator<T1,T2,RT> operator |(T1 a, InfixOperator<T1,T2,RT> b)
{
return new InfixOperator<T1,T2,RT>(a, b.function);
}
}



wizzard: (Default)

logic should be separated from emotions, they should be, they should spice the choice, but they shouldnt make it

Profile

wizzard: (Default)
wizzard

January 2019

S M T W T F S
  12 345
6789101112
1314 1516171819
202122 23242526
2728293031  

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 24th, 2025 07:53 pm
Powered by Dreamwidth Studios