diff --git a/lib/preface_make/free_selective.ml b/lib/preface_make/free_selective.ml index 773e224e..01fd6778 100644 --- a/lib/preface_make/free_selective.ml +++ b/lib/preface_make/free_selective.ml @@ -37,7 +37,7 @@ module Over_functor (F : Preface_specs.Functor.CORE) = struct ;; end - module S = Selective.Over_functor (Functor) (Core) + module S = Selective.Over_functor_via_select (Functor) (Core) module Transformation (Selective : Preface_specs.Selective.CORE) = struct type natural_transformation = { transform : 'a. 'a f -> 'a Selective.t } diff --git a/lib/preface_make/selective.ml b/lib/preface_make/selective.ml index e272abc8..0f310924 100644 --- a/lib/preface_make/selective.ml +++ b/lib/preface_make/selective.ml @@ -1,6 +1,24 @@ open Preface_core.Fun -module Core_over_functor +module Branch_via_select + (Functor : Preface_specs.Functor.CORE) + (Select : Preface_specs.Selective.CORE_WITH_SELECT + with type 'a t = 'a Functor.t) = +struct + let branch s l r = + let a = Functor.map Either.(map_right left) s + and b = Functor.map (compose_right_to_left Either.right) l in + Select.select (Select.select a b) r + ;; +end + +module Select_via_branch + (Select : Preface_specs.Selective.CORE_WITH_PURE_AND_BRANCH) = +struct + let select x y = Select.branch x y (Select.pure id) +end + +module Core_over_functor_via_select (Functor : Preface_specs.Functor.CORE) (Select : Preface_specs.Selective.CORE_WITH_PURE_AND_SELECT with type 'a t = 'a Functor.t) : @@ -16,29 +34,59 @@ module Core_over_functor let apply f x = select (map Either.left f) (map ( |> ) x) end + include Branch_via_select (Functor) (Select) include Applicative.Core_via_apply (Ap) end -module Core_over_applicative +module Core_over_functor_via_branch + (Functor : Preface_specs.Functor.CORE) + (Branch : Preface_specs.Selective.CORE_WITH_PURE_AND_BRANCH + with type 'a t = 'a Functor.t) : + Preface_specs.Selective.CORE with type 'a t = 'a Functor.t = struct + include Functor + include Branch + include Select_via_branch (Branch) + + module Ap = struct + type nonrec 'a t = 'a t + + let pure x = pure x + + let apply f x = select (map Either.left f) (map ( |> ) x) + end + + include Applicative.Core_via_apply (Ap) +end + +module Core_over_applicative_via_select (Applicative : Preface_specs.APPLICATIVE) (Select : Preface_specs.Selective.CORE_WITH_SELECT with type 'a t = 'a Applicative.t) : Preface_specs.Selective.CORE with type 'a t = 'a Applicative.t = struct include Applicative include Select + include Branch_via_select (Applicative) (Select) +end + +module Core_over_applicative_via_branch + (Applicative : Preface_specs.APPLICATIVE) + (Branch : Preface_specs.Selective.CORE_WITH_BRANCH + with type 'a t = 'a Applicative.t) : + Preface_specs.Selective.CORE with type 'a t = 'a Applicative.t = struct + include Applicative + include Branch + + include Select_via_branch (struct + let pure = pure + + include Branch + end) end module Operation (Core : Preface_specs.Selective.CORE) : Preface_specs.Selective.OPERATION with type 'a t = 'a Core.t = struct include Applicative.Operation (Core) - let branch s l r = - let open Core in - let a = map Either.(map_right left) s - and b = map (compose_right_to_left Either.right) l in - select (select a b) r - ;; - let if_ predicate if_true unless = let open Core in branch @@ -105,12 +153,12 @@ module Via module Syntax = Syntax end -module Over_functor +module Over_functor_via_select (Functor : Preface_specs.Functor.CORE) (Select : Preface_specs.Selective.CORE_WITH_PURE_AND_SELECT with type 'a t = 'a Functor.t) : Preface_specs.SELECTIVE with type 'a t = 'a Select.t = struct - module Core = Core_over_functor (Functor) (Select) + module Core = Core_over_functor_via_select (Functor) (Select) module Operation = Operation (Core) module Infix = Infix (Core) (Operation) module Syntax = Syntax (Core) @@ -120,12 +168,42 @@ module Over_functor include Syntax end -module Over_applicative +module Over_functor_via_branch + (Functor : Preface_specs.Functor.CORE) + (Branch : Preface_specs.Selective.CORE_WITH_PURE_AND_BRANCH + with type 'a t = 'a Functor.t) : + Preface_specs.SELECTIVE with type 'a t = 'a Branch.t = struct + module Core = Core_over_functor_via_branch (Functor) (Branch) + module Operation = Operation (Core) + module Infix = Infix (Core) (Operation) + module Syntax = Syntax (Core) + include Core + include Operation + include Infix + include Syntax +end + +module Over_applicative_via_select (Applicative : Preface_specs.APPLICATIVE) (Select : Preface_specs.Selective.CORE_WITH_SELECT with type 'a t = 'a Applicative.t) : Preface_specs.SELECTIVE with type 'a t = 'a Select.t = struct - module Core = Core_over_applicative (Applicative) (Select) + module Core = Core_over_applicative_via_select (Applicative) (Select) + module Operation = Operation (Core) + module Infix = Infix (Core) (Operation) + module Syntax = Syntax (Core) + include Core + include Operation + include Infix + include Syntax +end + +module Over_applicative_via_branch + (Applicative : Preface_specs.APPLICATIVE) + (Branch : Preface_specs.Selective.CORE_WITH_BRANCH + with type 'a t = 'a Applicative.t) : + Preface_specs.SELECTIVE with type 'a t = 'a Branch.t = struct + module Core = Core_over_applicative_via_branch (Applicative) (Branch) module Operation = Operation (Core) module Infix = Infix (Core) (Operation) module Syntax = Syntax (Core) diff --git a/lib/preface_make/selective.mli b/lib/preface_make/selective.mli index 84017e82..3ccb4ba1 100644 --- a/lib/preface_make/selective.mli +++ b/lib/preface_make/selective.mli @@ -6,20 +6,34 @@ Standard way to build [Selective Functor]. *) -(** Incarnation of a [Selective] over an [Applicative]. *) -module Over_applicative +(** Incarnation of a [Selective] over an [Applicative] using [select]. *) +module Over_applicative_via_select (Applicative : Preface_specs.APPLICATIVE) (Select : Preface_specs.Selective.CORE_WITH_SELECT with type 'a t = 'a Applicative.t) : Preface_specs.SELECTIVE with type 'a t = 'a Select.t -(** Incarnation of a [Selective] over a [Functor]. *) -module Over_functor +(** Incarnation of a [Selective] over an [Applicative] using branch. *) +module Over_applicative_via_branch + (Applicative : Preface_specs.APPLICATIVE) + (Branch : Preface_specs.Selective.CORE_WITH_BRANCH + with type 'a t = 'a Applicative.t) : + Preface_specs.SELECTIVE with type 'a t = 'a Branch.t + +(** Incarnation of a [Selective] over a [Functor] using [select] and [pure]. *) +module Over_functor_via_select (Functor : Preface_specs.Functor.CORE) (Select : Preface_specs.Selective.CORE_WITH_PURE_AND_SELECT with type 'a t = 'a Functor.t) : Preface_specs.SELECTIVE with type 'a t = 'a Select.t +(** Incarnation of a [Selective] over a [Functor] using [branch] and [pure]. *) +module Over_functor_via_branch + (Functor : Preface_specs.Functor.CORE) + (Branch : Preface_specs.Selective.CORE_WITH_PURE_AND_BRANCH + with type 'a t = 'a Functor.t) : + Preface_specs.SELECTIVE with type 'a t = 'a Branch.t + (** {2 Manual construction} Advanced way to build an [Selective Functor], constructing and assembling a @@ -34,20 +48,34 @@ module Via (Syntax : Preface_specs.Selective.SYNTAX with type 'a t = 'a Core.t) : Preface_specs.SELECTIVE with type 'a t = 'a Core.t -(** Incarnation of a [Selective.Core] over a [Functor]. *) -module Core_over_functor +(** Incarnation of a [Selective.Core] over a [Functor] via [select] and [pure]. *) +module Core_over_functor_via_select (Functor : Preface_specs.Functor.CORE) (Select : Preface_specs.Selective.CORE_WITH_PURE_AND_SELECT with type 'a t = 'a Functor.t) : Preface_specs.Selective.CORE with type 'a t = 'a Functor.t -(** Incarnation of a [Selective.Core] over an [Applicative]. *) -module Core_over_applicative +(** Incarnation of a [Selective.Core] over a [Functor] via [branch] and [pure]. *) +module Core_over_functor_via_branch + (Functor : Preface_specs.Functor.CORE) + (Branch : Preface_specs.Selective.CORE_WITH_PURE_AND_BRANCH + with type 'a t = 'a Functor.t) : + Preface_specs.Selective.CORE with type 'a t = 'a Functor.t + +(** Incarnation of a [Selective.Core] over an [Applicative] using [select]. *) +module Core_over_applicative_via_select (Applicative : Preface_specs.APPLICATIVE) (Select : Preface_specs.Selective.CORE_WITH_SELECT with type 'a t = 'a Applicative.t) : Preface_specs.Selective.CORE with type 'a t = 'a Applicative.t +(** Incarnation of a [Selective.Core] over an [Applicative] using [branch]. *) +module Core_over_applicative_via_branch + (Applicative : Preface_specs.APPLICATIVE) + (Branch : Preface_specs.Selective.CORE_WITH_BRANCH + with type 'a t = 'a Applicative.t) : + Preface_specs.Selective.CORE with type 'a t = 'a Applicative.t + (** Incarnation of [Selective.Operation] using [Selective.Core]. *) module Operation (Core : Preface_specs.Selective.CORE) : Preface_specs.Selective.OPERATION with type 'a t = 'a Core.t diff --git a/lib/preface_specs/selective.mli b/lib/preface_specs/selective.mli index b8a1a27f..f55ba8d8 100644 --- a/lib/preface_specs/selective.mli +++ b/lib/preface_specs/selective.mli @@ -4,6 +4,7 @@ (** {1 Structure anatomy} *) +(** Standard requirement with [select]. *) module type CORE_WITH_SELECT = sig type 'a t (** The type held by the [Selective]. *) @@ -13,6 +14,16 @@ module type CORE_WITH_SELECT = sig [Right]. *) end +(** Standard requirement with [branch]. *) +module type CORE_WITH_BRANCH = sig + type 'a t + (** The type held by the [Selective]. *) + + val branch : ('a, 'b) Either.t t -> ('a -> 'c) t -> ('b -> 'c) t -> 'c t + (** [branch] is like [select]. It chooses between two effects. *) +end + +(** Standard requirement including [pure] and [select]. *) module type CORE_WITH_PURE_AND_SELECT = sig include CORE_WITH_SELECT @@ -20,10 +31,20 @@ module type CORE_WITH_PURE_AND_SELECT = sig (** Create a new ['a t]. *) end -(** Standard requirement. *) +(** Standard requirement including [pure] and [branch]. *) +module type CORE_WITH_PURE_AND_BRANCH = sig + include CORE_WITH_BRANCH + + val pure : 'a -> 'a t + (** Create a new ['a t]. *) +end + +(** Standard requirement including Applicative requirements. *) module type CORE = sig include CORE_WITH_SELECT + include CORE_WITH_BRANCH with type 'a t := 'a t + include Applicative.CORE with type 'a t := 'a t (** Each [Selective] is also an [Applicative]. *) end @@ -36,9 +57,6 @@ module type OPERATION = sig include Applicative.OPERATION with type 'a t := 'a t (** Each [Selective] is also an [Applicative]. *) - val branch : ('a, 'b) Either.t t -> ('a -> 'c) t -> ('b -> 'c) t -> 'c t - (** [branch] is like [select]. It chooses between two effects. *) - val if_ : bool t -> 'a t -> 'a t -> 'a t (** Same of [branch] but using a [Boolean] as disjunction. *) diff --git a/lib/preface_stdlib/approximation.ml b/lib/preface_stdlib/approximation.ml index ac9192e9..d4948df0 100644 --- a/lib/preface_stdlib/approximation.ml +++ b/lib/preface_stdlib/approximation.ml @@ -10,7 +10,7 @@ module Over (M : Preface_specs.MONOID) = struct end) module Selective = - Preface_make.Selective.Over_applicative + Preface_make.Selective.Over_applicative_via_select (Applicative) (struct type nonrec 'a t = 'a t @@ -31,7 +31,7 @@ module Under (M : Preface_specs.MONOID) = struct end) module Selective = - Preface_make.Selective.Over_applicative + Preface_make.Selective.Over_applicative_via_select (Applicative) (struct type nonrec 'a t = 'a t diff --git a/lib/preface_stdlib/identity.ml b/lib/preface_stdlib/identity.ml index 08e8d0b3..1ed59ed2 100644 --- a/lib/preface_stdlib/identity.ml +++ b/lib/preface_stdlib/identity.ml @@ -27,7 +27,7 @@ module Monad = Preface_make.Monad.Via_bind (struct end) module Selective = - Preface_make.Selective.Over_applicative + Preface_make.Selective.Over_applicative_via_select (Applicative) (Preface_make.Selective.Select_from_monad (Monad)) diff --git a/lib/preface_stdlib/list.ml b/lib/preface_stdlib/list.ml index c1efc50e..980f3be5 100644 --- a/lib/preface_stdlib/list.ml +++ b/lib/preface_stdlib/list.ml @@ -96,7 +96,7 @@ module Monad_traversable (M : Preface_specs.MONAD) = module Monad = Preface_make.Traversable.Join_with_monad (Monad_plus) (Monad_traversable) module Selective = - Preface_make.Selective.Over_applicative + Preface_make.Selective.Over_applicative_via_select (Applicative) (Preface_make.Selective.Select_from_monad (Monad)) diff --git a/lib/preface_stdlib/nonempty_list.ml b/lib/preface_stdlib/nonempty_list.ml index 0615997b..43bc76d7 100644 --- a/lib/preface_stdlib/nonempty_list.ml +++ b/lib/preface_stdlib/nonempty_list.ml @@ -93,7 +93,7 @@ module Monad_traversable (M : Preface_specs.MONAD) = module Monad = Preface_make.Traversable.Join_with_monad (Monad_internal) (Monad_traversable) module Selective = - Preface_make.Selective.Over_applicative + Preface_make.Selective.Over_applicative_via_select (Applicative) (Preface_make.Selective.Select_from_monad (Monad)) diff --git a/lib/preface_stdlib/validation.ml b/lib/preface_stdlib/validation.ml index fec0d5f3..cb679f30 100644 --- a/lib/preface_stdlib/validation.ml +++ b/lib/preface_stdlib/validation.ml @@ -60,7 +60,7 @@ module Selective (Errors : Preface_specs.SEMIGROUP) = struct module A = Applicative (Errors) module S = - Preface_make.Selective.Over_applicative + Preface_make.Selective.Over_applicative_via_select (A) (struct type nonrec 'a t = ('a, Errors.t) t