diff --git a/fieldglass.ml b/fieldglass.ml index 81ed814..421c9ab 100644 --- a/fieldglass.ml +++ b/fieldglass.ml @@ -5,3 +5,7 @@ let lens ~view ~set = view, set let view (get, _) = get let set (_, put) = put let over (get, put) ~f source = put (f (get source)) source + +let compose (outer_get, outer_put) (inner_get, inner_put) = + (fun source -> inner_get (outer_get source)), + (fun value source -> outer_put (inner_put value (outer_get source)) source) diff --git a/fieldglass.mli b/fieldglass.mli index 75190ad..b220337 100644 --- a/fieldglass.mli +++ b/fieldglass.mli @@ -5,3 +5,4 @@ val lens : view:('s -> 'a) -> set:('b -> 's -> 't) -> ('s, 't, 'a, 'b) lens val view : ('s, 't, 'a, 'b) lens -> 's -> 'a val set : ('s, 't, 'a, 'b) lens -> 'b -> 's -> 't val over : ('s, 't, 'a, 'b) lens -> f:('a -> 'b) -> 's -> 't +val compose : ('s, 't, 'a, 'b) lens -> ('a, 'b, 'c, 'd) lens -> ('s, 't, 'c, 'd) lens diff --git a/runtime.ml b/runtime.ml index 9027da9..d858005 100644 --- a/runtime.ml +++ b/runtime.ml @@ -13,3 +13,10 @@ let () = let calls = ref 0 in assert (over sample ~f:(fun text -> incr calls; text ^ "s") source = ("colours", true)); assert (!calls = 1) + +let () = + let first = (fst, fun value (_, rest) -> value, rest) in + let second = (snd, fun value (rest, _) -> rest, value) in + let focus = compose first second in + assert (view focus ((true, "grey"), false) = "grey"); + assert (set focus 9 ((true, "grey"), false) = ((true, 9), false))