Hello,
I’m very new to F# and I’m exploring the idea of writing CI/CD pipelines with it.
I wrote the following types:
type Step<'a> = { Name: string; GetContext: (unit -> 'a); Run: ('a -> unit) }
type CompositeStep<'a> =
| Step of Step<'a>
| Sequential of string * CompositeStep<'a> list
| Parallel of string * CompositeStep<'a> list
Here is how I expect to use them:
let myPipeline =
Sequential("A pipeline", [
Step(step1)
Parallel("parallel stage", [
Step(step2)
Step(step3)
])
Step(step4) ]
)
Now, the problem is obvious, unless all the steps of your pipeline use the same context record type, you won’t be able to mix arbitrary steps. If you have steps with a different context type returned by GetContext, it won’t compile.
I tried to resolve this and it seems the only way this can work is if the parameter for a step is always obj
, which defeat the purpose of the type system for this particular case.
Ideally, I would like the Step type to be written like so:
type Step = { Name: string; GetContext: (unit -> 'a); Run: ('a -> unit) }
Here there is a type parameter shaping the relation between the functions in the record but this is not a parameter coming from Step (if that makes sense). Alas, it doesn’t seem to be allowed.
Am I missing something? Since I’m new to F#, I expect my approach to be somewhat wrong. Is there a better way to do this?
Thanks for your help.