I'm trying to create a bunch of types to generate a MIDI file to be played in a separate audio player (yes, I know there are libraries available... I'm using this as a way to learn). I created a single module signature (while attempting a functor solution) that the various modules containing these types are implementing. The signature looks like this (for now... string will be changed to bytes once I get a working template):
module type MIDIInterface = sig type t val encode : t -> string end
The various types I'm creating in different modules/files would be for the various types of MidiEvents: NoteOn, NoteOff, etc. All of them will have an encode function. Because each type is different (differing # of variables, differing event code, etc.), they can't just use the same encode function.
What I want to ultimately do is have a way to fold through all of the events of a song and call each events' encode function to create the full string (eventually bytestring) that can then be saved to a file.
I know I can just create a GADT to put make all of the various types the same type so that I can turn them into a giant list:
type Event = | NoteOn of NoteOnEvent | NoteOff of NoteOffEvent ...
...but this seems kind of a bulky solution, primarily because I'd have to update that type every time I create a new type. I also know that I can just implement them all under one type and just have one giant encode function:
let encode = function | (NoteOn time note velocity) -> ... | (NoteOff time note) -> ...
This is the solution I first tried in Haskell, and it was a nightmare to try to read through it when I was looking to reference something (one of the big reasons I'd like to break them into different types in different modules).
Is there a better solution in OCaml to be able to unify these various types based off the same signature without maintaining a big combinatory type into some sort of list/array/collection so that I can "fold encode empty collection_of_events"? If so, can you please let me know what this is called and where I can read up on how it works?