Как я могу сделать ленивый список, представляющий последовательность чисел удвоения? Пример:Ocaml: Lazy Lists
1 2 4 8 16 32
Как я могу сделать ленивый список, представляющий последовательность чисел удвоения? Пример:Ocaml: Lazy Lists
1 2 4 8 16 32
Великий блог цензовая ум имеет большую статью по этой теме:
http://enfranchisedmind.com/blog/posts/ocaml-lazy-lists-an-introduction/
Вы также можете проверить http://batteries.forge.ocamlcore.org/doc.preview%3Abatteries-beta1/html/api/Lazy%5Flist.html
, который является стандартной библиотеки для работы с этим ,
Этот вопрос также очень похоже на этот вопрос:
Первая ссылка больше не работает, они перемещают хост? – Oleg
@Oleg выглядит как домен истек. Такова жизнь в Интернете. Этот ответ почти 8 лет сейчас :) – chollida
В библиотеке Batteries теперь есть [три разных более или менее ленивых типа последовательности] (https://github.com/ocaml-batteries-team/batteries-included/wiki/ListTypes), с различными свойствами. – Mars
Использование потоков:
let f x = Stream.from (fun n -> Some (x * int_of_float (2.0 ** float_of_int n)))
или
let f x =
let next = ref x in
Stream.from (fun _ -> let y = !next in next := 2 * y ; Some y)
Использование пользовательского типа lazy_list
:
type 'a lazy_list =
| Nil
| Cons of 'a * 'a lazy_list lazy_t
let rec f x = lazy (Cons (x, f (2*x)))
Если вы хотите сделать это вручную, я бы сказал, что вы должны основные параметры:
использовать тип пользовательского lazy_list
, как ephemient сказал (за исключением его решение немного сломана) :
type 'a lazy_list =
| Nil
| Cons of 'a * 'a lazy_list
let head = function
| Nil -> failwith "Cannot extract head of empty list"
| Cons (h, _) -> h
let tail = function
| Nil -> failwith "Cannot extract tail of empty list"
| Cons (_, t) -> t
Используйте вид стука (как вещь используется для реализации ленивых вычислений на языке, который не поддерживает его). Вы определяете свой список как функцию unit -> 'a
, в котором говорится, как получить следующий элемент из текущего (нет необходимости использовать потоки для этого). Например, чтобы определить список всех натуральных чисел, вы можете сделать
let make_lazy_list initial next =
let lazy_list current() =
let result = !current in
current := (next !current); result
in lazy_list (ref initial)
let naturals = make_lazy_list 0 (function i -> i + 1)
КРП вы
print_int (naturals());
print_int (naturals());
print_int (naturals())
вы получите следующий результат:
0
1
2
Какая часть моего 'lazy_list' нарушена? Я не тестировал его, когда писал его, и я определенно больше знаком с Haskell и SML, чем с OCaml, но я тестировал его только сейчас, и он работает, на OCaml 3.11.1. Потоки в основном потому, что OP добавил комментарий к вопросу, запрашивающему потоки. – ephemient
Woops, вы правы, я действительно * действительно * неправильно читал это ... Плюс я не видел комментариев об использовании потоков. В следующий раз я надену очки: s. – jdb
Кроме того, в моем OCaml Network Application Environment Core Foundation есть ленивый модуль списка, который называется Cf_seq
. Фактически, я написал целую пачку функциональных структур данных. Все это доступно в соответствии с лицензией BSD с двумя предложениями. Наслаждаться.
Обновление: код был переименован в «Oni», и теперь он размещен в BitBucket. Вы также можете использовать пакет GODI.
Вы имеете в виду конкретную реализацию ленивых списков или просто общую концепцию? Кроме того, вам на самом деле нужен ленивый _lists_ (где значения, после вычисления, запоминаются), или вам просто нужен поток (где значения не сохраняются в памяти, и поэтому их можно прочитать только один раз)? –
Я ищу поток. –