Пытался разобраться с Y-комбинаторами по
статье на Хабре.
Более менее сабж осмыслил (возможность рекуррентного вызова анонимных функций), но попутно наткнулся на непонятную ошибку:
using System;
using System.Console;
using Nemerle;
using Nemerle.Utility;
module Program {
// Haskell-like
Fix[T](f : LazyValue[T] -> T) : T {
f(lazy(Fix(f)))
}
// C#-like
Fix[A, B](f : (A -> B) -> (A -> B)) : A -> B {
f(x => Fix(f)(x))
}
Main() : void {
// 1 - Haskell
def factCore = f => x => if(x <= 0) 1 else x * f.Value(x - 1);
def fact = Fix(factCore);
WriteLine(fact(5));
// 2 - C#
def factCore = f => x => if(x <= 0) 1 else x * f(x - 1);
def fact = Fix(factCore);
WriteLine(fact(5));
// 3 - Haskell
def genCore = f => (index, item) => if(index <= 0) [] else item :: f.Value(index - 1, item);
def gen = Fix(genCore);
WriteLine(gen(5, 42));
// 4 - C#
def genCore = f => (index, item) => if(index <= 0) [] else item :: f(index - 1, item);
def gen = Fix(genCore);
WriteLine(gen(5, 42));
_ = ReadKey(true);
}
}
Код 1 и 2 реализует банальный факториал, примеры 3 и 4 — генерируют список из index элементов item.
Весь код компилируется и работает. Кроме 4-го.
Выполнение 4-го примера приводит к банальному AV:
System.AccessViolationException was unhandled
Message: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.