If Set is Core.Set, one option is to use Set.Make_binable. Which is effectively:
module S = struct
include Set.Make(Foo)
include Provide_bin_io(Foo)
end
If Set is Core.Set, a second option assuming the common case where functors are unnecessary (although I’m not completely sure offhand whether it works for bin_io specifically, as opposed to e.g. hash where it surely works), is to add include (val Comparator.create ...) to Foo, at which point you can create Set.empty (module Foo) and type whatever = Set.M(Foo).t [@@deriving bin_io].
Finally, if Set is Stdlib.Set or something else that doesn’t provide a bin_io implementation, you’d have to use Core.Binable.Make_binable (you just need to provide conversions to a type that’s binable, like Foo.t list), or more manually but perhaps more efficiently Bin_prot.Utils.Make_iterable_binable.