From: David T. <Dav...@un...> - 2008-05-18 18:27:39
Attachments:
lazylist_0_3.tgz
|
Hi, I've tried to send a patch a few weeks ago but, for some reason, it seems that this patch never reached the mailing-list. I'm trying again to send a first patch. This patch involves * addition of two functions to module [Option]: [enum] (which allows enumerating the contents of an [Option.t]) and [get_exn] (a generalisation of [get]) * two new modules, [LazyList] and [LazyListLabels], for Haskell-style lazy lists. I hope that the patch will reach you, this time. I'm waiting for feedback before contributing an improved [Enum] and a number of other modules. Cheers, David -- David Teller Security of Distributed Systems http://www.univ-orleans.fr/lifo/Members/David.Teller Angry researcher: French Universities need reforms, but the LRU act brings liquidations. |
From: Janne H. <jjh...@gm...> - 2008-05-18 20:28:07
|
Hi David, What kind of example uses did you have in mind for the Option additions? Not sure if I agree that get_exn is too useful an addition. If Not_found for the (often erroneous) case of (Option.get None) is not generic enough, couldn't you just match the option and throw the exception yourself: match o with None -> raise your_exception | Some f -> f What's the use case for Option.enum? Janne On Sun, May 18, 2008 at 9:29 PM, David Teller <Dav...@un...> wrote: > Hi, > > I've tried to send a patch a few weeks ago but, for some reason, it > seems that this patch never reached the mailing-list. > > I'm trying again to send a first patch. This patch involves > * addition of two functions to module [Option]: [enum] (which allows > enumerating the contents of an [Option.t]) and [get_exn] (a > generalisation of [get]) > * two new modules, [LazyList] and [LazyListLabels], for Haskell-style > lazy lists. > > I hope that the patch will reach you, this time. I'm waiting for > feedback before contributing an improved [Enum] and a number of other > modules. > > Cheers, > David > > > -- > David Teller > Security of Distributed Systems > http://www.univ-orleans.fr/lifo/Members/David.Teller > Angry researcher: French Universities need reforms, but the LRU act brings > liquidations. > > ------------------------------------------------------------------------- > This SF.net email is sponsored by: Microsoft > Defy all challenges. Microsoft(R) Visual Studio 2008. > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > _______________________________________________ > ocaml-lib-devel mailing list > oca...@li... > https://lists.sourceforge.net/lists/listinfo/ocaml-lib-devel > > |
From: David T. <Dav...@un...> - 2008-05-18 21:56:17
|
Hi, 1) For [get_exn], I reason that, with ExtLib's conventions, when writing a module for a new data structure, one often has to write two functions: * some_kind_of_get : 'a t -> 'a option * some_kind_of_get': 'a t -> 'a (**raises [ThisModule.NotFound] *) Having [Option.get_exn] makes it possible to write the second function from the first one as a (real) one-liner. 2) For [Option.enum], it's not a big deal, just a matter of uniformisation wrt other containers. I consider also adding [iter] and [filter]. Cheers, David On Sun, 2008-05-18 at 23:28 +0300, Janne Hellsten wrote: > Hi David, > > What kind of example uses did you have in mind for the Option > additions? > > Not sure if I agree that get_exn is too useful an addition. If > Not_found for the (often erroneous) case of (Option.get None) is not > generic enough, couldn't you just match the option and throw the > exception yourself: > > match o with None -> raise your_exception | Some f -> f > > What's the use case for Option.enum? > > Janne -- David Teller Security of Distributed Systems http://www.univ-orleans.fr/lifo/Members/David.Teller Angry researcher: French Universities need reforms, but the LRU act brings liquidations. |
From: blue s. <blu...@gm...> - 2008-05-19 06:59:04
Attachments:
option.ml.diff
option.mli.diff
|
> 2) For [Option.enum], it's not a big deal, just a matter of > uniformisation wrt other containers. I consider also adding [iter] and > [filter]. Enum already have iter and filter. As it is supposed to provide a common layer for those kinds of operation, i'm not sure iter and filter are that useful. An of_enum would be useful, though (is it ok for those function not to be one to one mapping ?). >> What's the use case for Option.enum? For example, if you have an enumeration of options, and you want to "flatten" it into an enumeration of the base type (you're not interested in the failure cases) : Enum.concat (Enum.map Option.enum your_option_enum) Speaking of the Option module, I have a suggestion for a monadic "bind" function (a celebrity in the Haskell world, would imho be useful in OCaml too) : let bind f = function | None -> None | Some v -> f v (patches against .ml and .mli attached) It looks very much like map, except that the given function decides wether the result is a failure or a success. A typical use case would be the evaluation of an arithmetic AST (eg. a Sum data type), with an "eval" function that can fail, and thus returns an int option : let rec eval : ast -> int option = function | Num n -> Some n | ... | Sum (a, b) -> Option.bind (fun a' -> Option.bind (fun b' -> a' + b') (eval b)) (eval a) Option.bind allows one to compose possibly-failing operations. The parameters order (first the function, then the option) was choosen to be coherent with the other functions of the Option module. Haskellers are more used to the reverse order of the >>= operator (an infix version of bind), with the option first, allowing for a more natural style : eval a >>= fun a' -> eval b >>= fun b' -> a' + b' I think keeping the old order is a good compromise for now (moreover, the type is more elegant with the function first). If you're interested in the >>= syntaxic sugar too, i'd be happy to provide such an infix operator with reversed parameters. |
From: blue s. <blu...@gm...> - 2008-05-19 07:03:34
|
Sorry, silly mistake : fun b' -> Some (a' + b') On 5/19/08, blue storm <blu...@gm...> wrote: >> 2) For [Option.enum], it's not a big deal, just a matter of >> uniformisation wrt other containers. I consider also adding [iter] and >> [filter]. > > Enum already have iter and filter. As it is supposed to provide a > common layer for those kinds of operation, i'm not sure iter and > filter are that useful. An of_enum would be useful, though (is it ok > for those function not to be one to one mapping ?). > >>> What's the use case for Option.enum? > > For example, if you have an enumeration of options, and you want to > "flatten" it into an enumeration of the base type (you're not > interested in the failure cases) : > Enum.concat (Enum.map Option.enum your_option_enum) > > > > Speaking of the Option module, I have a suggestion for a monadic > "bind" function (a celebrity in the Haskell world, would imho be > useful in OCaml too) : > > let bind f = function > | None -> None > | Some v -> f v > (patches against .ml and .mli attached) > > It looks very much like map, except that the given function decides > wether the result is a failure or a success. > > A typical use case would be the evaluation of an arithmetic AST (eg. a > Sum data type), with an "eval" function that can fail, and thus > returns an int option : > > let rec eval : ast -> int option = function > | Num n -> Some n > | ... > | Sum (a, b) -> Option.bind (fun a' -> Option.bind (fun b' -> a' + b') > (eval b)) (eval a) > > Option.bind allows one to compose possibly-failing operations. > > The parameters order (first the function, then the option) was choosen > to be coherent with the other functions of the Option module. > Haskellers are more used to the reverse order of the >>= operator (an > infix version of bind), with the option first, allowing for a more > natural style : > eval a >>= fun a' -> eval b >>= fun b' -> a' + b' > > I think keeping the old order is a good compromise for now (moreover, > the type is more elegant with the function first). If you're > interested in the >>= syntaxic sugar too, i'd be happy to provide such > an infix operator with reversed parameters. > |
From: Richard J. <ri...@an...> - 2008-05-19 09:43:42
|
On Sun, May 18, 2008 at 11:28:08PM +0300, Janne Hellsten wrote: > What kind of example uses did you have in mind for the Option additions? > > Not sure if I agree that get_exn is too useful an addition. I disagree: I think that as long as additional functions maintain a consistent style with the rest of the library, are working, documented and useful to someone, and don't consume any more "module namespace", then there shouldn't be any barrier to adding them. In this case I have no problem with David's additional functions, the patches are fine[1], and I would be inclined to add them. Rich. [1] David: please always post unified diffs as in your second email, not tarballs as in the first. -- Richard Jones Red Hat |
From: Amit D. <ad...@du...> - 2008-05-19 09:53:56
|
Hi, I think the original idea behind ExtLib is that functions are either highly used and small or fairly commonly used and complicated. I think some people were using it for embedded applications, and are worried about code bloat. get_exn is fairly simple, and as Option.get already returns the fairly general Not_found exception, my impression is that it won't be highly used. That said, there are cases where a new function with a different exception might be handy. E.g. Invalid_argument in array's returning the index number which caused the problem... -Amit On Mon, May 19, 2008 at 10:43 AM, Richard Jones <ri...@an...> wrote: > On Sun, May 18, 2008 at 11:28:08PM +0300, Janne Hellsten wrote: >> What kind of example uses did you have in mind for the Option additions? >> >> Not sure if I agree that get_exn is too useful an addition. > > I disagree: I think that as long as additional functions maintain a > consistent style with the rest of the library, are working, documented > and useful to someone, and don't consume any more "module namespace", > then there shouldn't be any barrier to adding them. > > In this case I have no problem with David's additional functions, the > patches are fine[1], and I would be inclined to add them. > > Rich. > > [1] David: please always post unified diffs as in your second email, > not tarballs as in the first. > > -- > Richard Jones > Red Hat > > ------------------------------------------------------------------------- > This SF.net email is sponsored by: Microsoft > Defy all challenges. Microsoft(R) Visual Studio 2008. > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > _______________________________________________ > ocaml-lib-devel mailing list > oca...@li... > https://lists.sourceforge.net/lists/listinfo/ocaml-lib-devel > |
From: David T. <Dav...@un...> - 2008-05-21 21:17:29
|
On Mon, 2008-05-19 at 08:59 +0200, blue storm wrote: > > 2) For [Option.enum], it's not a big deal, just a matter of > > uniformisation wrt other containers. I consider also adding [iter] and > > [filter]. > > Enum already have iter and filter. As it is supposed to provide a > common layer for those kinds of operation, i'm not sure iter and > filter are that useful. An of_enum would be useful, though (is it ok > for those function not to be one to one mapping ?). I'm willing to write [of_enum], if people consider it interesting. What should it do if there is more than one element in the enumeration ? Raise an error or just consume the first element ? > >> What's the use case for Option.enum? > > For example, if you have an enumeration of options, and you want to > "flatten" it into an enumeration of the base type (you're not > interested in the failure cases) : > Enum.concat (Enum.map Option.enum your_option_enum) As usual, you have a point. > Speaking of the Option module, I have a suggestion for a monadic > "bind" function (a celebrity in the Haskell world, would imho be > useful in OCaml too) : [...] If we have to write a bind, I'd keep it consistent with other OCaml-based binds, i.e. in the same order as Haskell. Cheers, David -- David Teller Security of Distributed Systems http://www.univ-orleans.fr/lifo/Members/David.Teller Angry researcher: French Universities need reforms, but the LRU act brings liquidations. |
From: blue s. <blu...@gm...> - 2008-05-22 07:06:58
|
On 5/21/08, David Teller <Dav...@un...> wrote: > What should it do if there is more than one element in the enumeration ? > Raise an error or just consume the first element ? If think consuming the first element only is the saner decision. It's the strategy used by monadic sums, and the C-ish bool_of_int translation (0 -> false, everythin else -> true, so there is an information loss). Besides, it totally makes sense (when you think of option as a failure/success representation) that Option.of_enum (Enum.filter ...) behaves roughly as an Enum.find. > If we have to write a bind, I'd keep it consistent with other > OCaml-based binds, i.e. in the same order as Haskell. And it's the order that pa_monad use. Agreed. Below is a new patch with the usual parameters order. Against option.mli : 32a33,35 > val bind : 'a option -> ('a -> 'b option) -> 'b option > (** [bind None f] returns [None] and [bind (Some x) f] returns [f x] *) > Against option.ml : 26a27,30 > let bind opt f = match opt with > | None -> None > | Some v -> f v > Quick usage test : # let may_sum a b = Option.bind a (fun a_val -> Option.bind b (fun b_val -> Some (a_val + b_val)));; val may_sum : int option -> int option -> int option = <fun> # may_sum (Some 1) (Some 2), may_sum (Some 2) None;; - : int option * int option = (Some 3, None) |