Пытался разобраться с 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.
Здравствуйте, hardcase, Вы писали:
PEVerify ругается
[найдено ref 'Nemerle.Builtins.Function`2
[Nemerle.Builtins.Function`3
[System.Int32
,System.Int32
,Nemerle.Core.list`1[System.Int32]
]
,Nemerle.Builtins.Function`3
[System.Int32
,System.Int32
,Nemerle.Core.list`1[System.Int32]
]
]'
]
[ожидалось ref 'Nemerle.Builtins.Function`2
[Nemerle.Builtins.Function`2
[Nemerle.Builtins.Tuple`2[System.Int32,System.Int32]
,Nemerle.Core.list`1[System.Int32]
]
,Nemerle.Builtins.Function`2
[Nemerle.Builtins.Tuple`2[System.Int32,System.Int32]
,Nemerle.Core.list`1[System.Int32]
]
]'
] Непредусмотренный тип в стеке.
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, hardcase, Вы писали:
WH>PEVerify ругается
Действительно, изменение 4го примера (добавление скобок) волшебным образом избавило от проблемы:
def genCore = f => (index, item) => if(index <= 0) [] else item :: f( (index - 1, item) );
def gen = Fix(genCore);
WriteLine(gen(5, 42));
Похоже наблюдаются какие-то проблемы с развертыванием/свертыванием кортежей при вызове функций.
Здравствуйте, hardcase, Вы писали:
Короче скормил сие багтрекеру:
http://nemerle.rsdn.ru/bugs/view.php?id=1199