По мотивам обсуждения про перегрузку операторов, решил повозиться с функциями высшего порядка и наткнулся вот на такую ошибку времени выполнения.
using System.Console;
public module FuncHelper
{
public Pipe(fab : int->int, fbc : int->void) : int->void
{
match( fab : object ) {
| fa is void->int => (_ => fbc(fa()));
| _ => (x : int => fbc(fab(x)));
}
}
}
public module FuncHelper2
{
public Pipe[A, B, C](fab : A->B, fbc : B->C) : A->C
{
match( fab : object ) {
| fa is void->B => (_ => fbc(fa()));
| _ => (x : A => fbc(fab(x)));
}
}
}
def d2i( x : int ) : int { x+1; }
def print( x : int ) : void { WriteLine(x); }
//1
def f = match( d2i : object ) {
| fa is void->int => (_ => print(fa()));
| _ => x : int => print(d2i(x));
};
f(6);
//2
def f = FuncHelper.Pipe(d2i, print);
f(7);
//3
def f = FuncHelper2.Pipe.[int, int, void](d2i, print);
f(8);
Характерно, что код всех трех случаев в общем-то делает одно и то же. Но в первых двух на экран выводяться 7 и 8 соответственно, а в третьем случае генерируется ошибка обращения к памяти.
P.S. Версия компилятора 0.9.3
Здравствуйте, AngeL B., Вы писали:
AB>P.S. Версия компилятора 0.9.3
Для тестирования всегда бери самую свежую из SVN. Со времен 0.9.3 уже очень много изменений (в т.ч. и пофиксенных багов).
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Здравствуйте, AngeL B., Вы писали:
AB>По мотивам обсуждения про перегрузку операторов, решил повозиться с функциями высшего порядка и наткнулся вот на такую ошибку времени выполнения.
AB>AB>//3
AB>def f = FuncHelper2.Pipe.[int, int, void](d2i, print);
AB>f(8);
AB>
Вообще должна быть ошибка времени компиляции, т.к. void не может быть generic параметром.
Но по какой-то причине подставляется не void, а object,.. а поскольку изза ограничений .Net int->int и int->void это совсем разные вещи, то даже PEVerify говорит, что что-то не те типы передаем в Pipe.
Сейчас поглядим где надо проверку вставить.