Есть ли способ получить какие-то рекурсивно типизированные функции на Цейлоне? Например, я могу определить комбинаторную логику на Ceylon безопасным для типов способом следующим образом:
class Fi(shared Fi(Fi) o) { }
Fi veritas =
Fi((Fi t) =>
Fi((Fi f) =>
t));
Fi perfidas =
Fi((Fi t) =>
Fi((Fi f) =>
f));
Fi si =
Fi((Fi l) =>
Fi((Fi m) =>
Fi((Fi n) =>
l.o(m).o(n))));
print(si.o(veritas).o(veritas).o(perfidas) == veritas);
print(si.o(perfidas).o(veritas).o(perfidas) == perfidas);
print(si.o(veritas).o(perfidas).o(veritas) == perfidas);
print(si.o(perfidas).o(perfidas).o(veritas) == veritas);
Этот код работает по назначению. Однако для ясности, краткости и применимости к другим проблемам я хотел бы иметь возможность реализовать это поведение, используя только функции. Возьмем что-то вроде следующего (нерабочего) примера:
alias Fi => Fi(Fi);
Fi veritas(Fi t)(Fi f) => t;
Fi perfidas(Fi t)(Fi f) => f;
Fi si(Fi l)(Fi m)(Fi n) => l(m)(n);
print(si(veritas)(veritas)(perfidas) == veritas);
print(si(perfidas)(veritas)(perfidas) == perfidas);
print(si(veritas)(perfidas)(veritas) == perfidas);
print(si(perfidas)(perfidas)(veritas) == veritas);
В версии с псевдонимом функции тип Fi представляет функции, чьи операнды и возвращаемые значения могут составляться бесконечно. Обратите внимание, что из-за их рекурсивной природы типы Fi, Fi(Fi) и Fi(Fi)(Fi) можно считать функционально эквивалентными; все, что знает потребитель любого из них, это то, что если у них есть функция, которая при вызове на Fi даст им другой Fi.
Вот мое понимание того, что в настоящее время поддерживает Ceylon:
- Рекурсивные псевдонимы не поддерживаются, так как они стираются во время компиляции.
- Я не знаю ни одной текущей функции Ceylon, которую можно было бы использовать для рекурсивной специализации типа Callable или иным образом получить необходимый вид бесконечной цепочки.
- возможно связанный с этим вопрос получил отрицательный ответ. Однако это было два с половиной года назад, до того, как некоторые потенциально связанные функции, такие как функции типов, были реализованы в Ceylon 1.2 и пара из блоги, написанные Гэвином Кингом о поддержке функций нового типа.
- Существует проблема github с дженериками более высокого порядка.
- Существует еще одна проблема github, связанная с разрешением пользовательских реализаций Callable.
Можно ли реализовать желаемое поведение в текущей версии Ceylon? Или это определенно потребует одной или обеих из вышеупомянутых функций невыполненной работы?