Привет!
Знает ли кто нибудь как передать список в качестве параметров обычной (curryied) функции в Caml?
Примерно так:
let apply_list f list = ...
let sum = apply_list (+) [1; 2]
Начал понемногу разбираться с OCaml и стали появляться "глупые вопросы"
Задачка возникла во время распития чая на даче, после дня физических упражнений

Первоначально захотел реализовать Лиспообразный map: берущий функцию и список списков и возвращающий список.
Другими словами
map f [[x1; x2; ...]; [y1; y2; ...]; ...] -> [(f x1 y1 ...); (f x2 y2 ...); ...]
Упёрся в первую функцию — если её написать то задача решается

Ясно что транспонировав список списков или используя список кортежей/записей задача решается элементарно.
Вопрос в ограничениях синтаксиса языка.
--
Yami ga watashi to issyoni iku.
Здравствуйте, 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...
Здравствуйте, sirGrey, Вы писали:
G>Знает ли кто нибудь как передать список в качестве параметров обычной (curryied) функции в Caml?
G>Примерно так:
G>let apply_list f list = ...
G>let sum = apply_list (+) [1; 2]
В общем виде это невозможно. Я в своё время размышлял над этим, и пришёл к выводу, что функции неопределённой арности, разрушая систему типов Хиндли-Милнера, ничего особо хорошего взамен не дают. То есть диспатч по каждой следующей арности надо делать ручками, и это правильно
Здравствуйте, sirGrey, Вы писали:
G>Начал понемногу разбираться с OCaml и стали появляться "глупые вопросы"
G>Задачка возникла во время распития чая на даче, после дня физических упражнений
G>Первоначально захотел реализовать Лиспообразный map: берущий функцию и список списков и возвращающий список.
G>Другими словами
G>map f [[x1; x2; ...]; [y1; y2; ...]; ...] -> [(f x1 y1 ...); (f x2 y2 ...); ...]
На Хаскеле есть семейство функций zipWithN для этой задачи. Сделать список списков — это не лисповый map,
т.к. список списков — имеет тип [a]], а в лиспе что то вроде [a],[b],[c]...]
Если не привязываться именно к списку списков, но постараться универсально сделать подобную лиспу функцию,
то есть один приём для твоей задачи. Могу нарисовать на Хаскеле, наверняка на Окамле будет несложнее:
(<<) :: [a -> b] -> [a] -> [b]
(f:fs) << (x:xs) = f x : (fs << xs)
_ << _ = []
-- и дальше
map f xs1 << xs2 << xs3
Разумеется, в отличие от лиспа здесь придётся заранее знать кол-во "столбцов"

Собственно, это кол-во определяется типом функции f :: a -> b -> c -> .. -> r
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
G>Вопрос в ограничениях синтаксиса языка.
вопрос в строгой типизации. надо перестраивать мышление от динамических языков к статическим. судя по твоим темам, ты борешься не с теми демонами
Здравствуйте, BulatZiganshin, Вы писали:
G>>Вопрос в ограничениях синтаксиса языка.
BZ>вопрос в строгой типизации. надо перестраивать мышление от динамических языков к статическим. судя по твоим темам, ты борешься не с теми демонами
Я не борюсь

— я читаю SICP, знакомлюсь с OCaml и программирую на Java (Swing + EJB + custom DAO + Oracle).
Данный вопрос — это вообще-то "idle curiosity"

Интересно можно ли токое сделать — хотя бы чисто теоритически.
Интуитивно
чуйствую что используя бесконечные рекурсивные типы — можно, но для более рационального рассуждения математической базы всё-таки не хватает

--
Beatus vir qui suffert tentationem,
Quoniam cum probatus fuerit
Accipiet coronam vitae,