Bifunctors generalise containers whose items contain two pieces of data, and where we can map over both of them at the same time:
type ('a, 'b) t
val bimap : f1:('a -> 'b) -> f2:('c -> 'd) -> ('a, 'c) t -> ('b, 'd) t
This pattern comes up in several places in OCaml/Core:
pairs (t = Tuple2.t);
associative lists (t = List.Assoc.t);
results (t = Result).
It'd be nice if travesty supported this (though I figure the name would be Bi_mappable or something similar). It'd also be nice if travesty supported fixing the type of the first or second item; for example,
type elt
type 'b t (* 'a has become elt *)
val bimap : f1:(elt -> elt) -> f2:('a -> 'b) -> 'a t -> 'b t
and likewise for the other side. (This would be especially helpful for working with Or_error.t—it'd let you combine mapping over results and errors.)
Clown and Joker, which convert a bifunctor to a functor by focusing on the left or right side respectively (though I'd probably not use these names 😁);
Bitraversable, eg generalise Traversable in the same way that Bifunctor generalises Functor;
Maybe explore some of the other things going on in that package.
Bifunctors generalise containers whose items contain two pieces of data, and where we can map over both of them at the same time:
This pattern comes up in several places in OCaml/Core:
t = Tuple2.t
);t = List.Assoc.t
);t = Result
).It'd be nice if
travesty
supported this (though I figure the name would beBi_mappable
or something similar). It'd also be nice iftravesty
supported fixing the type of the first or second item; for example,and likewise for the other side. (This would be especially helpful for working with
Or_error.t
—it'd let you combine mapping over results and errors.)Another possibility is to implement a few of the ideas from the bifunctors Haskell library:
Clown
andJoker
, which convert a bifunctor to a functor by focusing on the left or right side respectively (though I'd probably not use these names 😁);Bitraversable
, eg generaliseTraversable
in the same way thatBifunctor
generalisesFunctor
;