#ocaml #utop #ocaml-lwt
#ocaml #utop #ocaml-lwt
Вопрос:
Я не понимаю, почему функция печати Lwt Lwt_io.print
имеет тип string -> unit Lwt.t
, но если я запускаю Lwt_io.print "a" >>= fun () -> Lwt_io.print "b";;
результат, то печатается «ab» и возвращается тип unit .
Я бы предположил, что это будет ошибка типа, поскольку Lwt_io.print возвращает единицу Lwt.t, а не единицу. Почему вызывается вторая часть потока?
Ответ №1:
Я подозреваю, что вы путаетесь, потому utop
что ведете себя умно.
Если вы посмотрите на документацию utop, в ней написано
при использовании библиотек lwt или async UTop автоматически ожидает значений [‘a Lwt.t] или [‘a Deferred.t] и возвращает [‘a] вместо этого
Вот почему
Lwt_io.print "a" >>= fun () -> Lwt_io.print "b";;
похоже, имеет тип unit
. Чтобы увидеть реальный тип, попробуйте выполнить следующее
let res = Lwt_io.print "a" >>= fun () -> Lwt_io.print "b";;
#show res;;
Вы увидите, что, когда получите то, что ожидали, unit Lwt.t
Обновить:
Просто чтобы прояснить ситуацию с типами, у нас есть
let f = fun () -> Lwt_io.print "b"
val ( >>= ) : 'a Lwt.t -> ('a -> 'b Lwt.t) -> 'b Lwt.t
val print : string -> unit Lwt.t
val f : unit -> unit Lwt.t
Lwt_io.print "a"
поэтому возвращает a unit Lwt.t
.
Это первый параметр (>>=)
, и 'a
поэтому unit
. Второй параметр (>>=)
is f
. f
принимает a unit
, который нам нужен, как 'a
есть unit
. Он возвращает a unit Lwt.t
, поэтому 'b
также unit
. Это означает, что конечным результатом будет a unit Lwt.t
.
Комментарии:
1. Итак, если это действительно тип
unit Lwt.t
, почему результатLwt_io.print "a"
активирует следующую функцию, для которой требуется единица измерения.2. Я только что обновил ответ, чтобы дать более подробную информацию о типах.
Ответ №2:
В Utop[1] toplevel lwt
и async
выражения автоматически выполняются с Lwt_main.run
и Thread_safe.block_on_async_exn
соответственно.
Чтобы отключить это, запустите
UTop.set_auto_run_lwt false;; (* for lwt *)
UTop.set_auto_run_async false;; (* for async *)