Я играл с D, пытаясь имитировать curryable functions в стиле Scalaпутем объединения лямбда-выражений.
Я пришел к следующему:
immutable foo=function(immutable int x)=>(immutable int y)=>(x+y);
struct S
{
static immutable foo=function(immutable int x)=>(immutable int y)=>(x+y);
}
class C static immutable foo=function(immutable int x)=>(immutable int y)=>(x+y);
}
void main()
{
writefln("global\t%s",foo(1)(2));
writefln("struct\t%s",S.foo(1)(2));
writefln("class\t%s",C.foo(1)(2));
}
Вот что я получаю, когда запускаю его:
global 3
struct 1528543170
Segmentation fault
Как видите, мой метод хорошо работает для глобальной функциональной переменной, но статическая функциональная переменная структуры дает ненужный результат, и переменная статической функции класса полностью терпит неудачу.
Если я удалю x
из возвращаемого выражения - function(immutable int x)=>(immutable int y)=>(y)
- версия структуры дает правильный результат(2
), но версия класса по-прежнему не работает.
Если я использую обычный метод вместо функциональной переменной:
immutable foo=function(immutable int x)=>(immutable int y)=>(x+y);
struct S
{
static auto foo(immutable int x)
{
return (immutable int y)=>(x+y);
}
}
class C
{
static auto foo(immutable int x)
{
return (immutable int y)=>(x+y);
}
}
void main()
{
writefln("global\t%s",foo(1)(2));
writefln("struct\t%s",S.foo(1)(2));
writefln("class\t%s",C.foo(1)(2));
}
он работает просто отлично:
global 3
struct 3
class 3
И я также получаю преимущество от использования делегатов (компилятор не разрешал делегаты в первой версии) - но этот стиль менее элегантен.
Я хорошо знаю, что D имеет функцию curry
в библиотеке std.functional
для каррирования функций, но иногда более удобно сделать функцию каррируемой по умолчанию, и кроме того - Мне любопытно узнать, почему моя первая версия не работает.
Есть идеи?
ОБНОВЛЕНИЕ
OK, Я зарегистрировал ошибку.Я еще немного покопался, и оказалось, что список аргументов foo
сдвигается, и поэтому x
получает ненужные данные.