Здравствуйте, sirGrey, Вы писали:
В принципе, такое можно, но будет очень громоздко, потому что мешает статическая типизация.
Если не возражаете, покажу пример на Хаскелле. С небольшими переделками его можно и на Окамле реализовать (думаю, это не трудно, просто я в Камлях так и не разобрался из-за Хаскелла
Если пытаться напрямую реализовать это применение, то мы упрёмся в такой вариант:
f3 a b c = a + b * c
eval1 f [a] = f a
eval2 f [a, b] = f a b
eval3 f [a, b, c] = f a b c -- и т.д.
main = do
print $ eval1 (1+) [1] -- 2
print $ eval2 (+) [1, 2] -- 3
print $ eval3 f3 [1, 2, 3] -- 7
Как видите, мы вынуждены создать разные применители (evalx) для функций f с разной арностью.
Можно воспользоваться алгебраическими типами данных и получить полиморфный вариант:
f3 a b c = a + b * c
data Eval a b = Eval1 (a -> b)
| Eval2 (a -> a -> b)
| Eval3 (a -> a -> a -> b) -- и т.д.
eval (Eval1 f) [a] = f a
eval (Eval2 f) [a, b] = f a b
eval (Eval3 f) [a, b, c] = f a b c -- и т.д.
main = do
print $ eval (Eval1 (1+)) [1] -- 2
print $ eval (Eval2 (+)) [1, 2] -- 3
print $ eval (Eval3 f3 ) [1, 2, 3] -- 7
Естественно, нужно ещё как-то проследить, что бы в списке было ровно столько элементов, сколько аргументов у применяемой к ним функции f...