v0.12-preview.120.18+252
This commit is contained in:
parent
6b33250bda
commit
de8312ead0
@ -1,6 +1,6 @@
|
|||||||
The MIT License
|
The MIT License
|
||||||
|
|
||||||
Copyright (c) 2015--2018 Jane Street Group, LLC <opensource@janestreet.com>
|
Copyright (c) 2015--2019 Jane Street Group, LLC <opensource@janestreet.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
9
Makefile
9
Makefile
@ -1,18 +1,17 @@
|
|||||||
INSTALL_ARGS := $(if $(PREFIX),--prefix $(PREFIX),)
|
INSTALL_ARGS := $(if $(PREFIX),--prefix $(PREFIX),)
|
||||||
|
|
||||||
# Default rule
|
|
||||||
default:
|
default:
|
||||||
jbuilder build @install
|
dune build
|
||||||
|
|
||||||
install:
|
install:
|
||||||
jbuilder install $(INSTALL_ARGS)
|
dune install $(INSTALL_ARGS)
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
jbuilder uninstall $(INSTALL_ARGS)
|
dune uninstall $(INSTALL_ARGS)
|
||||||
|
|
||||||
reinstall: uninstall install
|
reinstall: uninstall install
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf _build
|
dune clean
|
||||||
|
|
||||||
.PHONY: default install uninstall reinstall clean
|
.PHONY: default install uninstall reinstall clean
|
||||||
|
1
dune-project
Normal file
1
dune-project
Normal file
@ -0,0 +1 @@
|
|||||||
|
(lang dune 1.5)
|
2
expander/dune
Normal file
2
expander/dune
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
(library (name ppx_let_expander) (public_name ppx_let.expander)
|
||||||
|
(libraries base ppxlib) (preprocess no_preprocessing))
|
@ -1,7 +0,0 @@
|
|||||||
(library (
|
|
||||||
(name ppx_let_expander)
|
|
||||||
(public_name ppx_let.expander)
|
|
||||||
(libraries (base ppxlib))
|
|
||||||
(preprocess no_preprocessing)))
|
|
||||||
|
|
||||||
(jbuild_version 1)
|
|
@ -9,6 +9,7 @@ module List = struct
|
|||||||
match l with
|
match l with
|
||||||
| [] -> invalid_arg "List.reduce_exn"
|
| [] -> invalid_arg "List.reduce_exn"
|
||||||
| hd :: tl -> fold_left tl ~init:hd ~f
|
| hd :: tl -> fold_left tl ~init:hd ~f
|
||||||
|
;;
|
||||||
end
|
end
|
||||||
|
|
||||||
module Extension_name = struct
|
module Extension_name = struct
|
||||||
@ -20,22 +21,26 @@ module Extension_name = struct
|
|||||||
|
|
||||||
let operator_name = function
|
let operator_name = function
|
||||||
| Bind | Bind_open -> "bind"
|
| Bind | Bind_open -> "bind"
|
||||||
| Map | Map_open -> "map"
|
| Map | Map_open -> "map"
|
||||||
|
;;
|
||||||
|
|
||||||
let to_string = function
|
let to_string = function
|
||||||
| Bind -> "bind"
|
| Bind -> "bind"
|
||||||
| Bind_open -> "bind_open"
|
| Bind_open -> "bind_open"
|
||||||
| Map -> "map"
|
| Map -> "map"
|
||||||
| Map_open -> "map_open"
|
| Map_open -> "map_open"
|
||||||
|
;;
|
||||||
end
|
end
|
||||||
|
|
||||||
let let_syntax ~modul : Longident.t =
|
let let_syntax ~modul : Longident.t =
|
||||||
match modul with
|
match modul with
|
||||||
| None -> Lident "Let_syntax"
|
| None -> Lident "Let_syntax"
|
||||||
| Some id -> Ldot (id.txt, "Let_syntax")
|
| Some id -> Ldot (id.txt, "Let_syntax")
|
||||||
|
;;
|
||||||
|
|
||||||
let open_on_rhs ~loc ~modul =
|
let open_on_rhs ~loc ~modul =
|
||||||
Located.mk ~loc (Longident.Ldot (let_syntax ~modul, "Open_on_rhs" ))
|
Located.mk ~loc (Longident.Ldot (let_syntax ~modul, "Open_on_rhs"))
|
||||||
|
;;
|
||||||
|
|
||||||
let eoperator ~loc ~modul func =
|
let eoperator ~loc ~modul func =
|
||||||
let lid : Longident.t = Ldot (let_syntax ~modul, func) in
|
let lid : Longident.t = Ldot (let_syntax ~modul, func) in
|
||||||
@ -44,30 +49,33 @@ let eoperator ~loc ~modul func =
|
|||||||
|
|
||||||
let expand_with_tmp_vars ~loc bindings expr ~f =
|
let expand_with_tmp_vars ~loc bindings expr ~f =
|
||||||
match bindings with
|
match bindings with
|
||||||
| [_] -> f ~loc bindings expr
|
| [ _ ] -> f ~loc bindings expr
|
||||||
| _ ->
|
| _ ->
|
||||||
let tmp_vars = List.map bindings ~f:(fun _ -> gen_symbol ~prefix:"__let_syntax" ()) in
|
let tmp_vars =
|
||||||
|
List.map bindings ~f:(fun _ -> gen_symbol ~prefix:"__let_syntax" ())
|
||||||
|
in
|
||||||
let s_rhs_tmp_var (* s/rhs/tmp_var *) =
|
let s_rhs_tmp_var (* s/rhs/tmp_var *) =
|
||||||
List.map2_exn bindings tmp_vars ~f:(fun vb var ->
|
List.map2_exn bindings tmp_vars ~f:(fun vb var ->
|
||||||
{ vb with pvb_expr = evar ~loc:vb.pvb_expr.pexp_loc var })
|
{ vb with pvb_expr = evar ~loc:vb.pvb_expr.pexp_loc var })
|
||||||
in
|
in
|
||||||
let s_lhs_tmp_var (* s/lhs/tmp_var *) =
|
let s_lhs_tmp_var (* s/lhs/tmp_var *) =
|
||||||
List.map2_exn bindings tmp_vars ~f:(fun vb var ->
|
List.map2_exn bindings tmp_vars ~f:(fun vb var ->
|
||||||
{ vb with pvb_pat = pvar ~loc:vb.pvb_pat.ppat_loc var })
|
{ vb with pvb_pat = pvar ~loc:vb.pvb_pat.ppat_loc var })
|
||||||
in
|
in
|
||||||
pexp_let ~loc Nonrecursive s_lhs_tmp_var (f ~loc s_rhs_tmp_var expr)
|
pexp_let ~loc Nonrecursive s_lhs_tmp_var (f ~loc s_rhs_tmp_var expr)
|
||||||
;;
|
;;
|
||||||
|
|
||||||
let bind_apply ~loc ~modul extension_name ~arg ~fn =
|
let bind_apply ~loc ~modul extension_name ~arg ~fn =
|
||||||
pexp_apply ~loc
|
pexp_apply
|
||||||
|
~loc
|
||||||
(eoperator ~loc ~modul (Extension_name.operator_name extension_name))
|
(eoperator ~loc ~modul (Extension_name.operator_name extension_name))
|
||||||
[(Nolabel, arg); (Labelled "f", fn)]
|
[ Nolabel, arg; Labelled "f", fn ]
|
||||||
;;
|
;;
|
||||||
|
|
||||||
let maybe_open extension_name ~to_open:module_to_open expr =
|
let maybe_open extension_name ~to_open:module_to_open expr =
|
||||||
let loc = expr.pexp_loc in
|
let loc = expr.pexp_loc in
|
||||||
match (extension_name : Extension_name.t) with
|
match (extension_name : Extension_name.t) with
|
||||||
| Bind | Map -> expr
|
| Bind | Map -> expr
|
||||||
| Bind_open | Map_open -> pexp_open ~loc Override (module_to_open ~loc) expr
|
| Bind_open | Map_open -> pexp_open ~loc Override (module_to_open ~loc) expr
|
||||||
;;
|
;;
|
||||||
|
|
||||||
@ -79,30 +87,41 @@ let expand_let extension_name ~loc ~modul bindings body =
|
|||||||
let rev_boths = List.rev_map bindings ~f:(fun vb -> vb.pvb_expr) in
|
let rev_boths = List.rev_map bindings ~f:(fun vb -> vb.pvb_expr) in
|
||||||
List.reduce_exn rev_boths ~f:(fun acc e ->
|
List.reduce_exn rev_boths ~f:(fun acc e ->
|
||||||
let loc = e.pexp_loc in
|
let loc = e.pexp_loc in
|
||||||
eapply ~loc (eoperator ~loc ~modul "both") [e; acc])
|
eapply ~loc (eoperator ~loc ~modul "both") [ e; acc ])
|
||||||
in
|
in
|
||||||
(* Build pattern [(P1, (P2, ...))] *)
|
(* Build pattern [(P1, (P2, ...))] *)
|
||||||
let nested_patterns =
|
let nested_patterns =
|
||||||
let rev_patts = List.rev_map bindings ~f:(fun vb -> vb.pvb_pat) in
|
let rev_patts = List.rev_map bindings ~f:(fun vb -> vb.pvb_pat) in
|
||||||
List.reduce_exn rev_patts ~f:(fun acc p ->
|
List.reduce_exn rev_patts ~f:(fun acc p ->
|
||||||
let loc = p.ppat_loc in
|
let loc = p.ppat_loc in
|
||||||
ppat_tuple ~loc [p; acc])
|
ppat_tuple ~loc [ p; acc ])
|
||||||
in
|
in
|
||||||
bind_apply ~loc ~modul extension_name ~arg:nested_boths
|
bind_apply
|
||||||
|
~loc
|
||||||
|
~modul
|
||||||
|
extension_name
|
||||||
|
~arg:nested_boths
|
||||||
~fn:(pexp_fun ~loc Nolabel None nested_patterns body)
|
~fn:(pexp_fun ~loc Nolabel None nested_patterns body)
|
||||||
;;
|
;;
|
||||||
|
|
||||||
let expand_match extension_name ~loc ~modul expr cases =
|
let expand_match extension_name ~loc ~modul expr cases =
|
||||||
bind_apply ~loc ~modul extension_name
|
bind_apply
|
||||||
|
~loc
|
||||||
|
~modul
|
||||||
|
extension_name
|
||||||
~arg:(maybe_open extension_name ~to_open:(open_on_rhs ~modul) expr)
|
~arg:(maybe_open extension_name ~to_open:(open_on_rhs ~modul) expr)
|
||||||
~fn:(pexp_function ~loc cases)
|
~fn:(pexp_function ~loc cases)
|
||||||
;;
|
;;
|
||||||
|
|
||||||
let expand_if extension_name ~loc expr then_ else_ =
|
let expand_if extension_name ~loc expr then_ else_ =
|
||||||
expand_match extension_name ~loc expr
|
expand_match
|
||||||
[ case ~lhs:(pbool ~loc true) ~guard:None ~rhs:then_
|
extension_name
|
||||||
|
~loc
|
||||||
|
expr
|
||||||
|
[ case ~lhs:(pbool ~loc true) ~guard:None ~rhs:then_
|
||||||
; case ~lhs:(pbool ~loc false) ~guard:None ~rhs:else_
|
; case ~lhs:(pbool ~loc false) ~guard:None ~rhs:else_
|
||||||
]
|
]
|
||||||
|
;;
|
||||||
|
|
||||||
let expand ~modul extension_name expr =
|
let expand ~modul extension_name expr =
|
||||||
let loc = expr.pexp_loc in
|
let loc = expr.pexp_loc in
|
||||||
@ -118,32 +137,38 @@ let expand ~modul extension_name expr =
|
|||||||
For reference, here is the relevant part of the parser:
|
For reference, here is the relevant part of the parser:
|
||||||
https://github.com/ocaml/ocaml/blob/4.07/parsing/parser.mly#L1628 *)
|
https://github.com/ocaml/ocaml/blob/4.07/parsing/parser.mly#L1628 *)
|
||||||
match vb.pvb_pat.ppat_desc, vb.pvb_expr.pexp_desc with
|
match vb.pvb_pat.ppat_desc, vb.pvb_expr.pexp_desc with
|
||||||
| Ppat_constraint (p, { ptyp_desc = Ptyp_poly ([], t1); _ }),
|
| ( Ppat_constraint (p, { ptyp_desc = Ptyp_poly ([], t1); _ })
|
||||||
Pexp_constraint (_, t2) when phys_equal t1 t2 -> p
|
, Pexp_constraint (_, t2) )
|
||||||
|
when phys_equal t1 t2 -> p
|
||||||
| _ -> vb.pvb_pat
|
| _ -> vb.pvb_pat
|
||||||
in
|
in
|
||||||
{ vb with
|
{ vb with
|
||||||
pvb_pat;
|
pvb_pat
|
||||||
pvb_expr = maybe_open extension_name ~to_open:(open_on_rhs ~modul) vb.pvb_expr;
|
; pvb_expr =
|
||||||
|
maybe_open extension_name ~to_open:(open_on_rhs ~modul) vb.pvb_expr
|
||||||
})
|
})
|
||||||
in
|
in
|
||||||
expand_with_tmp_vars ~loc bindings expr ~f:(expand_let extension_name ~modul)
|
expand_with_tmp_vars ~loc bindings expr ~f:(expand_let extension_name ~modul)
|
||||||
| Pexp_let (Recursive, _, _) ->
|
| Pexp_let (Recursive, _, _) ->
|
||||||
Location.raise_errorf ~loc "'let%%%s' may not be recursive"
|
Location.raise_errorf
|
||||||
|
~loc
|
||||||
|
"'let%%%s' may not be recursive"
|
||||||
(Extension_name.to_string extension_name)
|
(Extension_name.to_string extension_name)
|
||||||
| Pexp_match (expr, cases) ->
|
| Pexp_match (expr, cases) -> expand_match extension_name ~loc ~modul expr cases
|
||||||
expand_match extension_name ~loc ~modul expr cases
|
|
||||||
| Pexp_ifthenelse (expr, then_, else_) ->
|
| Pexp_ifthenelse (expr, then_, else_) ->
|
||||||
let else_ =
|
let else_ =
|
||||||
match else_ with
|
match else_ with
|
||||||
| Some else_ -> else_
|
| Some else_ -> else_
|
||||||
| None ->
|
| None ->
|
||||||
Location.raise_errorf ~loc "'if%%%s' must include an else branch"
|
Location.raise_errorf
|
||||||
|
~loc
|
||||||
|
"'if%%%s' must include an else branch"
|
||||||
(Extension_name.to_string extension_name)
|
(Extension_name.to_string extension_name)
|
||||||
in
|
in
|
||||||
expand_if extension_name ~loc ~modul expr then_ else_
|
expand_if extension_name ~loc ~modul expr then_ else_
|
||||||
| _ ->
|
| _ ->
|
||||||
Location.raise_errorf ~loc
|
Location.raise_errorf
|
||||||
|
~loc
|
||||||
"'%%%s' can only be used with 'let', 'match', and 'if'"
|
"'%%%s' can only be used with 'let', 'match', and 'if'"
|
||||||
(Extension_name.to_string extension_name)
|
(Extension_name.to_string extension_name)
|
||||||
in
|
in
|
||||||
|
@ -6,12 +6,8 @@ module Extension_name : sig
|
|||||||
| Bind_open
|
| Bind_open
|
||||||
| Map
|
| Map
|
||||||
| Map_open
|
| Map_open
|
||||||
|
|
||||||
val to_string : t -> string
|
val to_string : t -> string
|
||||||
end
|
end
|
||||||
|
|
||||||
val expand
|
val expand : modul:longident loc option -> Extension_name.t -> expression -> expression
|
||||||
: modul:longident loc option
|
|
||||||
-> Extension_name.t
|
|
||||||
-> expression
|
|
||||||
-> expression
|
|
||||||
|
|
||||||
|
16
ppx_let.opam
16
ppx_let.opam
@ -1,21 +1,21 @@
|
|||||||
opam-version: "1.2"
|
opam-version: "2.0"
|
||||||
maintainer: "opensource@janestreet.com"
|
maintainer: "opensource@janestreet.com"
|
||||||
authors: ["Jane Street Group, LLC <opensource@janestreet.com>"]
|
authors: ["Jane Street Group, LLC <opensource@janestreet.com>"]
|
||||||
homepage: "https://github.com/janestreet/ppx_let"
|
homepage: "https://github.com/janestreet/ppx_let"
|
||||||
bug-reports: "https://github.com/janestreet/ppx_let/issues"
|
bug-reports: "https://github.com/janestreet/ppx_let/issues"
|
||||||
dev-repo: "git+https://github.com/janestreet/ppx_let.git"
|
dev-repo: "git+https://github.com/janestreet/ppx_let.git"
|
||||||
|
doc: "https://ocaml.janestreet.com/ocaml-core/latest/doc/ppx_let/index.html"
|
||||||
license: "MIT"
|
license: "MIT"
|
||||||
build: [
|
build: [
|
||||||
["jbuilder" "build" "-p" name "-j" jobs]
|
["dune" "build" "-p" name "-j" jobs]
|
||||||
]
|
]
|
||||||
depends: [
|
depends: [
|
||||||
|
"ocaml" {>= "4.04.2"}
|
||||||
"base"
|
"base"
|
||||||
"jbuilder" {build & >= "1.0+beta18.1"}
|
"dune" {build & >= "1.5.1"}
|
||||||
"ppxlib" {>= "0.1.0"}
|
"ppxlib" {>= "0.4.0"}
|
||||||
]
|
]
|
||||||
available: [ ocaml-version >= "4.04.2" ]
|
synopsis: "Monadic let-bindings"
|
||||||
descr: "
|
description: "
|
||||||
Monadic let-bindings
|
|
||||||
|
|
||||||
Part of the Jane Street's PPX rewriters collection.
|
Part of the Jane Street's PPX rewriters collection.
|
||||||
"
|
"
|
||||||
|
2
src/dune
Normal file
2
src/dune
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
(library (name ppx_let) (public_name ppx_let) (kind ppx_rewriter)
|
||||||
|
(libraries base ppxlib ppx_let_expander) (preprocess no_preprocessing))
|
@ -1,8 +0,0 @@
|
|||||||
(library (
|
|
||||||
(name ppx_let)
|
|
||||||
(public_name ppx_let)
|
|
||||||
(kind ppx_rewriter)
|
|
||||||
(libraries (base ppxlib ppx_let_expander))
|
|
||||||
(preprocess no_preprocessing)))
|
|
||||||
|
|
||||||
(jbuild_version 1)
|
|
@ -10,11 +10,7 @@ let ext extension_name =
|
|||||||
;;
|
;;
|
||||||
|
|
||||||
let () =
|
let () =
|
||||||
Driver.register_transformation "let"
|
Driver.register_transformation
|
||||||
~extensions:[
|
"let"
|
||||||
ext Bind;
|
~extensions:[ ext Bind; ext Bind_open; ext Map; ext Map_open ]
|
||||||
ext Bind_open;
|
|
||||||
ext Map;
|
|
||||||
ext Map_open;
|
|
||||||
]
|
|
||||||
;;
|
;;
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
|
1
test/dune
Normal file
1
test/dune
Normal file
@ -0,0 +1 @@
|
|||||||
|
(executables (names test) (preprocess (pps ppx_let)))
|
@ -1,6 +0,0 @@
|
|||||||
(executables (
|
|
||||||
(names (test))
|
|
||||||
(preprocess (pps (ppx_let ppxlib.runner)))))
|
|
||||||
|
|
||||||
|
|
||||||
(jbuild_version 1)
|
|
@ -2,17 +2,26 @@
|
|||||||
|
|
||||||
module Let_syntax = struct
|
module Let_syntax = struct
|
||||||
type 'a t = T of 'a
|
type 'a t = T of 'a
|
||||||
|
|
||||||
let map (T x) ~f = T (f x)
|
let map (T x) ~f = T (f x)
|
||||||
let both (T x) (T y) = T (x, y)
|
let both (T x) (T y) = T (x, y)
|
||||||
|
|
||||||
module Open_on_rhs = struct
|
module Open_on_rhs = struct
|
||||||
let return x = T x
|
let return x = T x
|
||||||
let f x ~(doc:string) = T (x, doc)
|
let f x ~(doc : string) = T (x, doc)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
let _ = [%map_open let x = return 42 and y = f 42 in ()]
|
let _ =
|
||||||
[%%expect{|
|
[%map_open
|
||||||
Line _, characters 45-49:
|
let x = return 42
|
||||||
|
and y = f 42 in
|
||||||
|
()]
|
||||||
|
;;
|
||||||
|
|
||||||
|
[%%expect
|
||||||
|
{|
|
||||||
|
Line _, characters 12-16:
|
||||||
Error: This expression has type doc:string -> (int * string) Let_syntax.t
|
Error: This expression has type doc:string -> (int * string) Let_syntax.t
|
||||||
but an expression was expected of type 'a Let_syntax.t
|
but an expression was expected of type 'a Let_syntax.t
|
||||||
|}]
|
|}]
|
||||||
|
81
test/test.ml
81
test/test.ml
@ -1,31 +1,41 @@
|
|||||||
module Monad_example = struct
|
module Monad_example = struct
|
||||||
|
|
||||||
module X : sig
|
module X : sig
|
||||||
type 'a t
|
type 'a t
|
||||||
|
|
||||||
module Let_syntax : sig
|
module Let_syntax : sig
|
||||||
val return : 'a -> 'a t
|
val return : 'a -> 'a t
|
||||||
|
|
||||||
module Let_syntax : sig
|
module Let_syntax : sig
|
||||||
val return : 'a -> 'a t
|
val return : 'a -> 'a t
|
||||||
val bind : 'a t -> f:('a -> 'b t) -> 'b t
|
val bind : 'a t -> f:('a -> 'b t) -> 'b t
|
||||||
val map : 'a t -> f:('a -> 'b) -> 'b t
|
val map : 'a t -> f:('a -> 'b) -> 'b t
|
||||||
val both : 'a t -> 'b t -> ('a * 'b) t
|
val both : 'a t -> 'b t -> ('a * 'b) t
|
||||||
module Open_on_rhs : sig val return : 'a -> 'a t end
|
|
||||||
|
module Open_on_rhs : sig
|
||||||
|
val return : 'a -> 'a t
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end = struct
|
end = struct
|
||||||
type 'a t = 'a
|
type 'a t = 'a
|
||||||
|
|
||||||
let return x = x
|
let return x = x
|
||||||
let bind x ~f = f x
|
let bind x ~f = f x
|
||||||
let map x ~f = f x
|
let map x ~f = f x
|
||||||
let both x y = (x, y)
|
let both x y = x, y
|
||||||
|
|
||||||
module Let_syntax = struct
|
module Let_syntax = struct
|
||||||
let return = return
|
let return = return
|
||||||
|
|
||||||
module Let_syntax = struct
|
module Let_syntax = struct
|
||||||
let return = return
|
let return = return
|
||||||
let bind = bind
|
let bind = bind
|
||||||
let map = map
|
let map = map
|
||||||
let both = both
|
let both = both
|
||||||
module Open_on_rhs = struct let return = return end
|
|
||||||
|
module Open_on_rhs = struct
|
||||||
|
let return = return
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -35,50 +45,55 @@ module Monad_example = struct
|
|||||||
let _mf a : _ X.t =
|
let _mf a : _ X.t =
|
||||||
let%bind_open x = a in
|
let%bind_open x = a in
|
||||||
return (x + 1)
|
return (x + 1)
|
||||||
|
;;
|
||||||
|
|
||||||
let _mf' a b c : _ X.t =
|
let _mf' a b c : _ X.t =
|
||||||
let%bind_open x = a and y = b and (u, v) = c in
|
let%bind_open x = a
|
||||||
|
and y = b
|
||||||
|
and u, v = c in
|
||||||
return (x + y + (u * v))
|
return (x + y + (u * v))
|
||||||
|
;;
|
||||||
|
|
||||||
let _mg a : _ X.t =
|
let _mg a : _ X.t =
|
||||||
let%map x : int X.t = a in
|
let%map x : int X.t = a in
|
||||||
x + 1
|
x + 1
|
||||||
|
;;
|
||||||
|
|
||||||
let _mg' a b c : _ X.t =
|
let _mg' a b c : _ X.t =
|
||||||
let%map x = a and y = b and (u, v) = c in
|
let%map x = a
|
||||||
|
and y = b
|
||||||
|
and u, v = c in
|
||||||
x + y + (u * v)
|
x + y + (u * v)
|
||||||
|
;;
|
||||||
|
|
||||||
let _mh a : _ X.t =
|
let _mh a : _ X.t =
|
||||||
match%bind_open a with
|
match%bind_open a with
|
||||||
| 0 -> return true
|
| 0 -> return true
|
||||||
| _ -> return false
|
| _ -> return false
|
||||||
|
;;
|
||||||
|
|
||||||
let _mi a : _ X.t =
|
let _mi a : _ X.t =
|
||||||
match%map a with
|
match%map a with
|
||||||
| 0 -> true
|
| 0 -> true
|
||||||
| _ -> false
|
| _ -> false
|
||||||
|
;;
|
||||||
|
|
||||||
let _mif a : _ X.t =
|
let _mif a : _ X.t = if%bind_open a then return true else return false
|
||||||
if%bind_open a
|
let _mif' a : _ X.t = if%map a then true else false
|
||||||
then return true
|
|
||||||
else return false
|
|
||||||
|
|
||||||
let _mif' a : _ X.t =
|
|
||||||
if%map a
|
|
||||||
then true
|
|
||||||
else false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
module Applicative_example = struct
|
module Applicative_example = struct
|
||||||
|
|
||||||
module X : sig
|
module X : sig
|
||||||
type 'a t
|
type 'a t
|
||||||
|
|
||||||
module Let_syntax : sig
|
module Let_syntax : sig
|
||||||
val return : 'a -> 'a t
|
val return : 'a -> 'a t
|
||||||
|
|
||||||
module Let_syntax : sig
|
module Let_syntax : sig
|
||||||
val return : 'a -> 'a t
|
val return : 'a -> 'a t
|
||||||
val map : 'a t -> f:('a -> 'b) -> 'b t
|
val map : 'a t -> f:('a -> 'b) -> 'b t
|
||||||
val both : 'a t -> 'b t -> ('a * 'b) t
|
val both : 'a t -> 'b t -> ('a * 'b) t
|
||||||
|
|
||||||
module Open_on_rhs : sig
|
module Open_on_rhs : sig
|
||||||
val flag : int t
|
val flag : int t
|
||||||
val anon : int t
|
val anon : int t
|
||||||
@ -87,15 +102,19 @@ module Applicative_example = struct
|
|||||||
end
|
end
|
||||||
end = struct
|
end = struct
|
||||||
type 'a t = 'a
|
type 'a t = 'a
|
||||||
|
|
||||||
let return x = x
|
let return x = x
|
||||||
let map x ~f = f x
|
let map x ~f = f x
|
||||||
let both x y = (x, y)
|
let both x y = x, y
|
||||||
|
|
||||||
module Let_syntax = struct
|
module Let_syntax = struct
|
||||||
let return = return
|
let return = return
|
||||||
|
|
||||||
module Let_syntax = struct
|
module Let_syntax = struct
|
||||||
let return = return
|
let return = return
|
||||||
let map = map
|
let map = map
|
||||||
let both = both
|
let both = both
|
||||||
|
|
||||||
module Open_on_rhs = struct
|
module Open_on_rhs = struct
|
||||||
let flag = 66
|
let flag = 66
|
||||||
let anon = 77
|
let anon = 77
|
||||||
@ -121,10 +140,14 @@ module Applicative_example = struct
|
|||||||
let _ag a : _ X.t =
|
let _ag a : _ X.t =
|
||||||
let%map x = a in
|
let%map x = a in
|
||||||
x + 1
|
x + 1
|
||||||
|
;;
|
||||||
|
|
||||||
let _ag' a b c : _ X.t =
|
let _ag' a b c : _ X.t =
|
||||||
let%map x = a and y = b and (u, v) = c in
|
let%map x = a
|
||||||
|
and y = b
|
||||||
|
and u, v = c in
|
||||||
x + y + (u * v)
|
x + y + (u * v)
|
||||||
|
;;
|
||||||
|
|
||||||
(* {[
|
(* {[
|
||||||
let _ah a : _ X.t =
|
let _ah a : _ X.t =
|
||||||
@ -137,10 +160,12 @@ module Applicative_example = struct
|
|||||||
match%map a with
|
match%map a with
|
||||||
| 0 -> true
|
| 0 -> true
|
||||||
| _ -> false
|
| _ -> false
|
||||||
|
;;
|
||||||
end
|
end
|
||||||
|
|
||||||
module Example_without_open = struct
|
module Example_without_open = struct
|
||||||
let _ag a : _ Applicative_example.X.t =
|
let _ag a : _ Applicative_example.X.t =
|
||||||
let%map.Applicative_example.X.Let_syntax x = a in
|
let%map.Applicative_example.X.Let_syntax x = a in
|
||||||
x + 1
|
x + 1
|
||||||
|
;;
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user