diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 10e65ea..f4786c5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,7 @@ jobs: os: - ubuntu-latest ocaml-compiler: - - 5.4.x + - 5.5.x runs-on: ${{ matrix.os }} diff --git a/.github/workflows/deploy-doc.yml b/.github/workflows/deploy-doc.yml index ff8c6fa..2fe3f4e 100644 --- a/.github/workflows/deploy-doc.yml +++ b/.github/workflows/deploy-doc.yml @@ -37,7 +37,7 @@ jobs: - name: Setup OCaml uses: ocaml/setup-ocaml@dec6499fef64fc5d7ed43d43a87251b7b1c306f5 # v3.4.8 with: - ocaml-compiler: "5.4.x" + ocaml-compiler: "5.5.x" dune-cache: true opam-repositories: | default: https://github.com/ocaml/opam-repository.git diff --git a/.github/workflows/more-ci.yml b/.github/workflows/more-ci.yml index d18d525..4aaccdf 100644 --- a/.github/workflows/more-ci.yml +++ b/.github/workflows/more-ci.yml @@ -31,6 +31,7 @@ jobs: - macos-latest - ubuntu-latest ocaml-compiler: + - 5.5.x - 5.4.x - 5.3.x - 5.2.x @@ -38,7 +39,7 @@ jobs: exclude: # We exclude the combination already tested in the 'ci' workflow. - os: ubuntu-latest - ocaml-compiler: 5.4.x + ocaml-compiler: 5.5.x runs-on: ${{ matrix.os }} diff --git a/.github/workflows/test-deploy-doc.yml b/.github/workflows/test-deploy-doc.yml index 827406d..8354dcf 100644 --- a/.github/workflows/test-deploy-doc.yml +++ b/.github/workflows/test-deploy-doc.yml @@ -37,7 +37,7 @@ jobs: - name: Setup OCaml uses: ocaml/setup-ocaml@dec6499fef64fc5d7ed43d43a87251b7b1c306f5 # v3.4.8 with: - ocaml-compiler: "5.4.x" + ocaml-compiler: "5.5.x" dune-cache: true opam-repositories: | default: https://github.com/ocaml/opam-repository.git diff --git a/doc/docs/tutorials/provider-explicit/README.md b/doc/docs/tutorials/provider-explicit/README.md index 4bc8b97..9259234 100644 --- a/doc/docs/tutorials/provider-explicit/README.md +++ b/doc/docs/tutorials/provider-explicit/README.md @@ -20,17 +20,11 @@ let id (module A : Id) (x : A.t) = A.id x ;; ``` ```ansi -Line 7, characters 23-32: -7 | let id (module A : Id) (x : A.t) = A.id x ;; - ^^^^^^^^^ -Error: This pattern matches values of type A.t - but a pattern was expected which matches values of type 'a - The type constructor A.t would escape its scope +module type Id = sig type t val id : t -> t end +val id : (module A : Id) -> A.t -> A.t = ``` -As you can see above, constructs of these kinds are currently not in the -language, but they are introduced in the version `5.5` of OCaml. We'll make -sure to update that part of the doc when we migrate to these new features! +Constructs of these kinds were introduced in the version `5.5` of OCaml. Back to our tutorial: we titled it *provider-explicit* in reference to this. In the pattern we present here, functions take an additional *provider* @@ -174,7 +168,6 @@ module type Repeatable = sig end ``` - ```ocaml type repeatable = [ `Repeatable ] @@ -248,7 +241,7 @@ interface working on a parametrized type, a concept known as Consider values that can be mapped: ```ocaml -module type Mappable = sig +module type Mappable0 = sig type 'a t val map : 'a t -> f:('a -> 'b) -> 'b t @@ -258,15 +251,21 @@ end Imagine you want to write a function that applies the same mapping function multiple times for some reason. -This kind of higher-kinded polymorphism will be achievable using modular -explicit. It might look something like this in the future: +This kind of higher-kinded polymorphism is achievable using modular explicit: ```ocaml -let map_n_times (type a) (module A : Mappable) (x : a A.t) ~(f : a -> a) ~n = - let rec loop n x = if n = 0 then x else loop (n - 1) (A.map f x) in +let map_n_times (type a) (module A : Mappable0) (x : a A.t) ~(f : a -> a) ~n : a A.t = + let rec loop n x = if Int.equal n 0 then x else loop (n - 1) (A.map x ~f) in loop n x ;; -val map_n_times : (module A : Mappable) -> 'a A.t -> f:('a -> 'a) -> n:int -> 'a = +``` + +```ocaml +let%expect_test "map n times" = + let result = map_n_times (module List) [ 0; 1; 2 ] ~f:Int.succ ~n:10 in + print_dyn (result |> Dyn.list Dyn.int); + [%expect {| [ 10; 11; 12 ] |}] +;; ``` In this section we show how to do this with the *provider* library, leveraging @@ -306,9 +305,9 @@ end) ``` ```ansi -Line 2, characters 14-15: +Line 2, characters 16-17: 2 | val t : ('a 't, (module Mappable with type 'a t = 'a 't), [> mappable ]) Provider.Trait.t - ^ + ^ Error: Syntax error ``` diff --git a/doc/docs/tutorials/provider-explicit/provider_explicit.ml b/doc/docs/tutorials/provider-explicit/provider_explicit.ml index 605af31..b2466d9 100644 --- a/doc/docs/tutorials/provider-explicit/provider_explicit.ml +++ b/doc/docs/tutorials/provider-explicit/provider_explicit.ml @@ -44,12 +44,8 @@ let id (module A : Id) (x : A.t) = A.id x ;; ``` ```ansi - Line 7, characters 23-32: - 7 | let id (module A : Id) (x : A.t) = A.id x ;; - ^^^^^^^^^ - Error: This pattern matches values of type A.t - but a pattern was expected which matches values of type 'a - The type constructor A.t would escape its scope + module type Id = sig type t val id : t -> t end + val id : (module A : Id) -> A.t -> A.t = ``` |}]; () @@ -57,9 +53,7 @@ let id (module A : Id) (x : A.t) = A.id x ;; (* @mdexp - As you can see above, constructs of these kinds are currently not in the - language, but they are introduced in the version `5.5` of OCaml. We'll make - sure to update that part of the doc when we migrate to these new features! + Constructs of these kinds were introduced in the version `5.5` of OCaml. Back to our tutorial: we titled it *provider-explicit* in reference to this. In the pattern we present here, functions take an additional *provider* @@ -238,9 +232,7 @@ module type Repeatable = sig val repeat : t -> t end -(* @mdexp.end *) - -(* @mdexp +(* @mdexp.end @mdexp.code *) @@ -324,27 +316,38 @@ let%expect_test "double_then_repeat" = Consider values that can be mapped: - ```ocaml - module type Mappable = sig - type 'a t + @mdexp.code *) + +module type Mappable0 = sig + type 'a t - val map : 'a t -> f:('a -> 'b) -> 'b t - end - ``` + val map : 'a t -> f:('a -> 'b) -> 'b t +end + +(* @mdexp Imagine you want to write a function that applies the same mapping function multiple times for some reason. - This kind of higher-kinded polymorphism will be achievable using modular - explicit. It might look something like this in the future: + This kind of higher-kinded polymorphism is achievable using modular explicit: - ```ocaml - let map_n_times (type a) (module A : Mappable) (x : a A.t) ~(f : a -> a) ~n = - let rec loop n x = if n = 0 then x else loop (n - 1) (A.map f x) in - loop n x - ;; - val map_n_times : (module A : Mappable) -> 'a A.t -> f:('a -> 'a) -> n:int -> 'a = - ``` + @mdexp.code *) + +let map_n_times (type a) (module A : Mappable0) (x : a A.t) ~(f : a -> a) ~n : a A.t = + let rec loop n x = if Int.equal n 0 then x else loop (n - 1) (A.map x ~f) in + loop n x +;; + +(* @mdexp.end + @mdexp.code *) + +let%expect_test "map n times" = + let result = map_n_times (module List) [ 0; 1; 2 ] ~f:Int.succ ~n:10 in + print_dyn (result |> Dyn.list Dyn.int); + [%expect {| [ 10; 11; 12 ] |}] +;; + +(* @mdexp In this section we show how to do this with the *provider* library, leveraging the [higher_kinded](https://github.com/janestreet/higher_kinded) library. @@ -399,9 +402,9 @@ end) ``` ```ansi - Line 2, characters 14-15: + Line 2, characters 16-17: 2 | val t : ('a 't, (module Mappable with type 'a t = 'a 't), [> mappable ]) Provider.Trait.t - ^ + ^ Error: Syntax error ``` |}]; diff --git a/dune-project b/dune-project index b5a0fa4..5be2209 100644 --- a/dune-project +++ b/dune-project @@ -72,7 +72,7 @@ (allow_empty) (depends (ocaml - (>= 5.3)) + (>= 5.5)) (ocamlformat (= 0.29.0)) (bisect_ppx diff --git a/provider-dev.opam b/provider-dev.opam index cdfb2d4..aa3ea7c 100644 --- a/provider-dev.opam +++ b/provider-dev.opam @@ -9,7 +9,7 @@ doc: "https://mbarbin.github.io/provider/" bug-reports: "https://github.com/mbarbin/provider/issues" depends: [ "dune" {>= "3.20"} - "ocaml" {>= "5.3"} + "ocaml" {>= "5.5"} "ocamlformat" {= "0.29.0"} "bisect_ppx" {>= "2.8.3"} "dyn" {>= "3.20"}