Ответ 1
В настоящее время в OCaml есть две библиотеки, которые обеспечивают понимание списков, одна из которых ранее была частью OCaml Batteries, другая - с camlp4. Ни один из них не используется широко, и я лично не рекомендую вам использовать его.
Для понимания списка для работы вам необходимо изменить синтаксис языка. Это можно сделать с предварительной обработкой вашей программы, написанной расширенным синтаксисом, с препроцессором camlp4
. Кроме того, понимание списка не является гражданином первого класса в сообществе OCaml, и оно не поддерживается современными инструментариями. Несмотря на это, вы все равно можете легко играть с ним в топлексе, для этого вам нужно установить пакет для составления списка:
opam install pa_comprehension
и загрузите его в верхний слой, используя следующие директивы:
# #use "topfind";;
# #camlp4o;;
# #require "pa_comprehension";;
# open Batteries;;
# [? 2 * x | x <- 0 -- max_int ; x * x > 3 ?];;
Но опять же мое личное мнение о том, что понимание списка - не лучший способ структурировать ваш код.
Жизнь без понимания
Пример, который вы указали, может быть выражен с помощью модуля core_kernel
Sequence
(аналог батарей Enum
)
let f n =
Sequence.(range 0 n |>
filter ~f:(fun x -> x * x > 3) |>
map ~f:(fun x -> x * 2))
Следовательно, a filter |> map
является такой общей идиомой, существует функция filter_map
:
let f n =
Sequence.(range 0 n |>
filter_map ~f:(fun x ->
if x * x > 3 then Some (x * 2) else None))
Вы можете заметить, что эти примеры содержат больше кода, чем понимание списка. Но как только ваши программы начнут зрелы от простых мировых приложений с целыми числами до чего-то более сложного, вы согласитесь, что использование явных итераторов более читабельно и понятно.
Кроме того, поскольку библиотеки в Core
настолько согласованы, вы можете использовать простой List
вместо Sequence
, просто заменив последний на первый. Но, конечно, List
нетерпелив, в отличие от Sequence
, поэтому играть с max_int
с помощью списков не очень хорошая идея.
Кроме того, поскольку все контейнеры являются монадами, вы можете использовать монадические операторы для отображения, например:
let odds n = List.(range 0 n >>| fun x -> x * 2 + 1)