From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by walapai.inria.fr (8.13.6/8.13.6) with ESMTP id p8H9NwdA005552 for ; Sat, 17 Sep 2011 11:23:58 +0200 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AgUDAGJmdE6K54gDgWdsb2JhbABBhFWhDoF+FAEBFiYlgVMBAQQBIwRRAQULCw4MAgUWCwICCQMCAQIBRQYNAQcCh3MCogKRHIEshDuBEQSTSIUdjBE X-IronPort-AV: E=Sophos;i="4.68,397,1312149600"; d="scan'208";a="120207066" Received: from rouge.crans.org ([138.231.136.3]) by mail1-smtp-roc.national.inria.fr with ESMTP/TLS/ADH-AES256-SHA; 17 Sep 2011 11:23:53 +0200 Received: from localhost (localhost.crans.org [127.0.0.1]) by rouge.crans.org (Postfix) with ESMTP id 24A4F85D6; Sat, 17 Sep 2011 11:23:52 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at crans.org Received: from rouge.crans.org ([10.231.136.3]) by localhost (rouge.crans.org [10.231.136.3]) (amavisd-new, port 10024) with LMTP id pLt1eJIu1dK9; Sat, 17 Sep 2011 11:23:52 +0200 (CEST) Received: from [192.168.39.1] (fbx.up7.fr [81.56.96.177]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by rouge.crans.org (Postfix) with ESMTPSA id E408285CA; Sat, 17 Sep 2011 11:23:51 +0200 (CEST) Message-ID: <4E746727.3090804@glondu.net> Date: Sat, 17 Sep 2011 11:23:51 +0200 From: =?UTF-8?B?U3TDqXBoYW5lIEdsb25kdQ==?= User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.21) Gecko/20110831 Icedove/3.1.13 MIME-Version: 1.0 To: Dmitry Grebeniuk CC: caml-list References: <20110913183714.GA15241@yeeloong.happyleptic.org> <4E71CDB8.5020704@dogguy.org> <1316092241.28210.14.camel@aurora> In-Reply-To: X-Enigmail-Version: 1.1.2 OpenPGP: id=49881AD3 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from quoted-printable to 8bit by walapai.inria.fr id p8H9NwdA005552 Subject: Re: [Caml-list] Lwt and exceptions Le 17/09/2011 08:38, Dmitry Grebeniuk a écrit : > It does not respect the monad associativity: > > (m >>= f) >>= g == m >>= (fun x -> f x >>= g) > [...] > ============== > open Lwt; > > value () = Printf.printf "case 1, enter two lines:\n%!"; > value m = Lwt_io.read_line Lwt_io.stdin; > value f_v = Lwt_io.read_line Lwt_io.stdin; > value f = fun _ -> f_v; > value g = Lwt.return; > value res = (m >>= f) >>= g; > > (* > value () = Printf.printf "case 2, enter two lines:\n%!"; > value f_v = Lwt_io.read_line Lwt_io.stdin; > value m = Lwt_io.read_line Lwt_io.stdin; > value f = fun _ -> f_v; > value g = Lwt.return; > value res = m >>= (fun x -> f x >>= g); > *) > > value () = Lwt_main.run (res >>= fun s -> > Lwt_io.write_line Lwt_io.stdout ("res = " ^ s)); > ============== Using Lwt doesn't automatigally make OCaml purely functional... in your example, you change the order of m and f_v, which both do side-effects, so they are different in the two instances of res, so they cannot be compared. Can you give an example that involves only pure functions? > When I began to use Lwt, I was badly surprised > by the fact that Lwt.t values are not real I/O actions. > So I had to get a new habit: if the top-level module > value has type Lwt.t 'a, I have to defer its > computation by wrapping it under "fun () -> ". > And I have to remember which of my functions return > Lwt.t values, which of my abstract types really have > type Lwt.t 'a or contain the Lwt.t 'a values, to defer > their computations/sideeffects too. Maybe what you expected was something that encapsulates the IO monad too. Lwt doesn't do that: as with raw OCaml, IOs are direct with Lwt. Cheers, -- Stéphane