module type Partial = {
type partial
let reduce: (partial, 'action) => option<partial>
}
module Float = {
type partial = float
let reduce = (partial: partial, action: 'action): option<partial> => {
switch action {
| #Set(a) => ...
}
module Array = (E: Partial) => {
type structure<'e> = array<'e>
type partial = structure<E.partial>
let reduce = (p: partial, action: [#Index(int, 'action)]): option<partial> => {
switch action {
| #Index(index, action) => <find element, send action to element, recompose array>
}
and this fails with
Signature mismatch:
...
Values do not match:
let reduce: (partial, [> #Clear | #Set(partial)]) => option<partial>
is not included in
let reduce: (partial, 'action) => option<partial>
File "playground.res", line 3, characters 3-52: Expected declaration
File "playground.res", line 8, characters 7-13: Actual declaration
Any thoughts? Saying poly variant not in type parameter doesnt compute for me.
It seems like the type parameter is being resolved at the source module maybe and not at the calling-module?
I’m not sure if that’s feasible (anyone, feel free to correct me), but I’d also question if that’s a desirable design in the first place. How would the implementation of Either.reduce work?
This makes more sense to me:
type action = [#Left(L.partial) | #Right(R.partial) | #LAaction(L.action) | #RAction(R.action)]
Otherwise, if L.action and R.action share any of the same constructors, then it’s ambiguous how the reduce function should behave (even if it compiles).
My immediate application is a Sum where both sides are products with some equivalent fields. So id rather not have to be aware at the client level which value the sum is taking when i send a new action.
I could see both overlapping and non overlapping sums being useful, and available with either different Functors or some supplied policy module