Как превратить Ceylon Sequential или массив в универсальный Tuple с соответствующим типом?

У меня есть универсальная функция, которая должна создать кортеж для вызова функции, аргументы которой я не знаю, типы.

Как то так (кроме array в этом примере создается некоторый внешний код, поэтому я не могу просто применить функцию напрямую):

Result apply<Result, Where>(
    Anything[] array, 
    Callable<Result, Where> fun)
        given Where satisfies Anything[] => nothing;

Есть ли безопасный для типов способ реализовать этот метод и получить функцию, которая будет вызываться с заданными аргументами?

2 ответа

Решение

Это не может быть сделано полностью безопасно для типов... но при условии, что массив действительно содержит элементы правильных типов, как они должны появляться в кортеже типа Where, следующая функция сделает свое дело:

Tuple<Anything, Anything, Anything> typedTuple({Anything+} array) {
    if (exists second = array.rest.first) {
        return Tuple(array.first, typedTuple({ second }.chain(array.rest.rest)));
    }
    else {
        return Tuple(array.first, []);
    }
}

И применить осуществляется как:

Result apply<Result, Where>(
    [Anything+] array, 
    Callable<Result, Where> fun)
        given Where satisfies Anything[] {
    value tuple = typedTuple(array);
    assert(is Where tuple);
    return fun(*tuple);
}

Там нет ничего, касающегося типа array к параметрам fun, так что подпись не может быть реализована безопасным для типов способом. Вы не ограничиваете тип array совсем; это может содержать что угодно. Как в принципе реализация с безопасным типом справится со случаем, когда fun надеется [String, Integer] но array является [Boolean+]?

Другие вопросы по тегам