-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #32 from mbarbin/custom-higher-kinded
Use a custom higher kinded mini-library
- Loading branch information
Showing
13 changed files
with
182 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,8 @@ | |
"Doublable", | ||
"functors", | ||
"GADT", | ||
"injective", | ||
"injectivity", | ||
"janestreet", | ||
"kinded", | ||
"odoc", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
#require "provider" ;; | ||
#require "higher_kinded" ;; | ||
#require "provider-tests.higher_kinded" ;; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
(library | ||
(name higher_kinded) | ||
(public_name provider-tests.higher_kinded) | ||
(flags :standard -w +a-4-40-41-42-44-45-48-66 -warn-error +a) | ||
(instrumentation | ||
(backend bisect_ppx)) | ||
(lint | ||
(pps ppx_js_style -check-doc-comments)) | ||
(preprocess no_preprocessing)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
type !'a t | ||
type !'a hk = 'a t | ||
|
||
module type S = sig | ||
type 'a t | ||
type higher_kinded | ||
|
||
val inject : 'a t -> ('a -> higher_kinded) hk | ||
val project : ('a -> higher_kinded) hk -> 'a t | ||
end | ||
|
||
module Make (X : sig | ||
type 'a t | ||
end) : S with type 'a t := 'a X.t = struct | ||
type higher_kinded | ||
|
||
external inject : 'a X.t -> ('a -> higher_kinded) hk = "%identity" | ||
external project : ('a -> higher_kinded) hk -> 'a X.t = "%identity" | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
(** A minimal higher-kinded library for the purpose of tests and tutorials. | ||
This is a reduced variation on https://github.com/janestreet/higher_kinded | ||
that we use to explore ways the Provider library may be used with interfaces | ||
containing parametrized types. | ||
We use this small kernel rather than an upstream library because we needed | ||
to add some injectivity annotations to the types, and the higher-kinded | ||
libraries available do not have them at this time. Proposing this change | ||
upstream would require more thoughts, and so far we didn't have actual usage | ||
for this (outside of tests and tutorials), so we just went with this small | ||
kernel instead. *) | ||
|
||
type !'a t | ||
type !'a hk := 'a t | ||
|
||
module type S = sig | ||
type 'a t | ||
type higher_kinded | ||
|
||
val inject : 'a t -> ('a -> higher_kinded) hk | ||
val project : ('a -> higher_kinded) hk -> 'a t | ||
end | ||
|
||
module Make (X : sig | ||
type !'a t | ||
end) : S with type 'a t := 'a X.t |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
(* In this test we check that the trait system allows to be used with module | ||
interfaces that are parametrized. | ||
There is also a tutorial for this, but we like to have both. Motivations are: | ||
- here we get better error messages and development experience when working | ||
on this (the tutorial is an mdx file, which has a slightly less advanced | ||
editor integration). | ||
- this test is checked by [more-ci] whereas the tutorial is not. *) | ||
|
||
module type Mappable = sig | ||
type 'a t | ||
|
||
val map : 'a t -> f:('a -> 'b) -> 'b t | ||
|
||
type higher_kinded | ||
|
||
val inject : 'a t -> ('a -> higher_kinded) Higher_kinded.t | ||
val project : ('a -> higher_kinded) Higher_kinded.t -> 'a t | ||
end | ||
|
||
type mappable = [ `Mappable ] | ||
|
||
module Mappable : sig | ||
val t | ||
: ( ('a -> 'higher_kinded) Higher_kinded.t | ||
, (module Mappable with type higher_kinded = 'higher_kinded) | ||
, [> mappable ] ) | ||
Provider.Trait.t | ||
end = struct | ||
type (_, _, _) Provider.Trait.t += | ||
| Mappable : | ||
( ('a -> 'higher_kinded) Higher_kinded.t | ||
, (module Mappable with type higher_kinded = 'higher_kinded) | ||
, [> mappable ] ) | ||
Provider.Trait.t | ||
|
||
let t = Mappable | ||
end | ||
|
||
let map_n_times | ||
: type a t. | ||
((a -> t) Higher_kinded.t, [> mappable ]) Provider.Handler.t | ||
-> (a -> t) Higher_kinded.t | ||
-> int | ||
-> f:(a -> a) | ||
-> (a -> t) Higher_kinded.t | ||
= | ||
fun handler t n ~f -> | ||
let module M = (val Provider.Handler.lookup handler ~trait:Mappable.t) in | ||
let at = M.project t in | ||
let rec loop n at = if n = 0 then at else loop (n - 1) (M.map at ~f) in | ||
M.inject (loop n at) | ||
;; | ||
|
||
module Higher_kinded_list = struct | ||
include List | ||
include Higher_kinded.Make (List) | ||
end | ||
|
||
module Higher_kinded_array = struct | ||
include Array | ||
include Higher_kinded.Make (Array) | ||
end | ||
|
||
module _ : Mappable with type 'a t = 'a list = Higher_kinded_list | ||
module _ : Mappable with type 'a t = 'a array = Higher_kinded_array | ||
|
||
let mappable_list () | ||
: ( ('a -> Higher_kinded_list.higher_kinded) Higher_kinded.t | ||
, [> mappable ] ) | ||
Provider.Handler.t | ||
= | ||
Provider.Handler.make | ||
[ Provider.Trait.implement Mappable.t ~impl:(module Higher_kinded_list) ] | ||
;; | ||
|
||
let mappable_array () | ||
: ( ('a -> Higher_kinded_array.higher_kinded) Higher_kinded.t | ||
, [> mappable ] ) | ||
Provider.Handler.t | ||
= | ||
Provider.Handler.make | ||
[ Provider.Trait.implement Mappable.t ~impl:(module Higher_kinded_array) ] | ||
;; | ||
|
||
let%expect_test "map_n_times" = | ||
let r = | ||
map_n_times | ||
(mappable_list ()) | ||
(List.init 10 ~f:Fn.id |> Higher_kinded_list.inject) | ||
3 | ||
~f:(fun x -> x + 1) | ||
|> Higher_kinded_list.project | ||
in | ||
print_s [%sexp (r : int list)]; | ||
[%expect {| (3 4 5 6 7 8 9 10 11 12) |}]; | ||
let r = | ||
map_n_times | ||
(mappable_array ()) | ||
([| "a"; "b" |] |> Higher_kinded_array.inject) | ||
4 | ||
~f:(fun x -> x ^ x) | ||
|> Higher_kinded_array.project | ||
in | ||
print_s [%sexp (r : string array)]; | ||
[%expect {| (aaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbb) |}]; | ||
() | ||
;; |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters