OCaml
Обработка списка
Поиск…
List.Map
List.map имеет подпись ('a -> 'b) -> 'a list -> 'b list которая на английском языке является функцией, которая принимает функцию (мы будем называть это функцией отображения) от одного типа (а именно 'a ) другому типу (а именно 'b ) и списку первого типа. Функция возвращает список второго типа, где каждый элемент является результатом вызова функции сопоставления элемента первого списка.
List.map string_of_int [ 1; 2; 3; 4 ]
#- [ "1"; "2"; "3"; "4" ] : string list
Типы 'a и 'b не должны быть разными. Например, мы можем так же легко сопоставить числа с их квадратами.
let square x = x * x in
List.map square [ 1; 2; 3; 4 ]
#- [ 1; 4; 9; 16 ] : int list
Совокупные данные в списке
Функции List.fold_left и List.fold_right функции более высокого порядка , реализующие внешнюю логику агрегации списков. Объединение списка, иногда также называемого сокращением списка, означает вычисление значения, полученного после последовательного контроля всех элементов в этом списке.
В документации модуля List указано, что
-
List.fold_left fa [b1; ...; bn]являетсяf (... (f (fa b1) b2) ...) bn. -
List.fold_right f [a1; ...; an] b-f a1 (f a2 (... (f an b) ...)). (Эта последняя функция не является хвостовой рекурсивной.)
В простых английских вычислениях List.fold_left fa [b1; ...; bn] пробегает список [b1; ...; bn] отслеживание аккумулятора первоначально установлен в : каждый раз , когда мы видим элемент в списке, мы используем a f для обновления значения аккумулятора, и , когда мы закончили, аккумулятор является окончательным значением нашего вычисления. Функция List.fold_right похожа.
Вот несколько практических примеров:
Вычислить общую сумму списка номеров
List.fold_left ( + ) 0 lst
Вычислить среднее значение списка поплавков
let average lst =
let (sum, n) =
List.fold_left (fun (sum, n) x -> (sum +. x, n + 1)) (0.0, 0) lst
in
sum /. (float_of_int n)
Повторная реализация основной обработки списка
Функции List.fold_left и List.fold_right настолько общие, что их можно использовать для реализации почти всех других функций из модуля списка:
let list_length lst = (* Alternative implementation to List.length *)
List.fold_left ( + ) 0 lst
let list_filter predicate lst = (* Alternative implementation to List.filter *)
List.fold_right (fun a b -> if predicate a then a :: b else b) lst []
Также возможно переопределить функцию List.iter , помните, что () является глобальным состоянием программы для интерпретации этого кода в качестве дополнительного примера агрегации списка :
let list_iter f lst = (* Alternation implementation to List.iter *)
List.fold_left (fun () b -> f b) () lst
Эти примеры предназначены для изучения материала, эти реализации не имеют никакой добродетели над соответствующими функциями из стандартной библиотеки.