2015-01-30 4 views
1

У меня есть список 'a и one' b и функция типа 'a -> 'b-> 'c. Я пытаюсь применить функцию к каждому элементу списка с b, который у меня уже есть, и составить список «c». В haskell я бы сделал что-то вроде zipWith(foobar) a-list (replicate (length a) b). Каков эквивалентный способ сделать это в OCaml?Эквивалент zipwith от haskell в OCaml

+3

Я думаю, что описание проблемы путают ответы. Вы должны сказать «список» a и один «b», если я правильно понимаю. Кроме того, если это так, то даже в haskell вам не нужно 'zipWith', простая« карта »может решить вашу проблему. –

+3

Yikes. Скажите, что вы на самом деле никогда не писали 'zipWith f a (replicate (length a) b)'. Перемещение 'a' вдвое больше, чем это очень плохо для потокового поведения. Гораздо лучше написать 'zipWith f a (repeat b)'. – Carl

+0

Это было в прошлом, когда я впервые изучал Хаскелл, но да, да. –

ответ

8

Ну, в вашем примере вы на самом деле не нужно zipWith, вы можете использовать простой map:

List.map (fun a -> f a b) a_list 

Это было бы более эффективно, чем List.map2 (эквивалент zipWith), потому что OCaml не обрабатывает списки так же, как Haskell, поэтому построение фиктивного списка только ради итерации на самом деле не стоит.

+0

Я взял на себя смелость добавить какой-то контекст, так как сначала был смущен этим ответом - я ожидал, что это обеспечит то, что ОП задал, а не то, что нужно OP. – chi

+0

Спасибо! В следующий раз я постараюсь быть яснее. – PatJ

7

"List.map2" является эквивалентом Хаскеля "zipWith"

val map2 : ('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list 
+0

op имеет только один 'b', а не' list 'b' –

+2

Это отвечает на вопрос, как указано в заголовке, что полезно для будущих посетителей. –

+0

@MartinJambon hmm Я согласен –

1

Эквивалент в OCaml будет:

open Core_kernel.Std 

let replicate n b = List.init n ~f:(fun _ -> b) 
List.(map2_exn a (replicate (length b) b) ~f:your_function) 

Этот код возникает несколько вопросов, однако. Например, вы уверены, что хотите, чтобы список был вторым аргументом вашей функции? И в чем причина дублирования второго аргумента, вместо того, чтобы передавать его как свободную переменную в вашу функцию, как предположил @PatJ. И это не все о ленивой и нетерпеливой оценке. В Haskell вам все равно нужно пройти по списку, и b будет пройден дважды. Тот факт, что вычисление является ленивым, не означает, что он будет быстрее, когда он будет оценен.

Но, тем не менее, библиотека Core OCaml предоставляет ленивый список с именем Sequence, который похож на Haskell's. Код будет таким же, по модулю имени модуля, т. Е. Просто замените List на Sequence.

+0

Ну, я мало знаю о поведении Хаскелла и полагаю, что он был оптимизирован без проверки. (ленивый я: -p) – PatJ