Я думаю, что вам может потребоваться указать сигнатуру для аргумента функции getres
.На основании сообщения об ошибке компилятор делает вывод, что fn
принимает один аргумент и возвращает результат.Таким образом, в строке ошибки f1
это не функция, а значение.То есть.карринг не происходит.
Но это не относится к последнему случаю, когда вы хотите выполнить функцию, а не выполнять частичное применение.Вам может понадобиться дополнительный уровень косвенности, чтобы справиться с этим.(В других языках .NET для этого нужно было бы использовать отражение - что позволяет вызывать функцию с передачей массива параметров - это может быть невозможно в строго типизированном языке .NET, чтобы справиться с этим без отражения.)
Дополнительно (для обобщения комментариев ниже):
Рассмотрим обязательную подпись getres
.Если fn
является функцией двух аргументов (т.е. 'a -> 'a -> 'b
), тогда getres
имеет подпись:
('a -> 'a -> 'b) -> list 'a -> ('a -> 'b`)
для первого вызова.
Но когда этот экземплярgetres
делает свой рекурсивный вызов, он должен быть функцией, принимающей один аргумент, т.е.его подпись должна быть:
('a -> 'b) -> list 'a -> 'b`
Это невозможно с одной функцией F #.
Это возможно с функцией .NET (т. Е. Членом класса), но только если каждый «уровень» написан отдельно (т. Е. Жесткое кодирование максимального количества аргументов).(Сравните, как System.Func<T1, TRes>
, System.Func<T1, T2, TRes>
определены во время выполнения .NET.)
(Это то, с чем динамические языки могут легко справиться, но для языков со строгой типизацией нужна очень сложная система типов, лежащая в основеэто добиться.)