I'm essentially needing to know how to write a function like this...
joinCommands :: forall e1 e2 e3
. Union e1 e2 e3
=> Eff e1 Unit
-> Eff e2 Unit
-> Eff e3 Unit
joinCommands fn1 fn2 = do
fn1
fn2
Which doesn't work. I get this error:
[PureScript] Could not match kind
Control.Monad.Eff.Effect
with kind
Type
More specifically, what I'm trying to do is combine two Arrays of user-supplied functionality. That is one part of the codebase (user supplied) returns Array (Eff e1 Unit)
and another part (also user supplied) returns Array (Eff e2 Unit)
. And at the application's entrypoint (the "core" unaccessable to the user) those two sets need to combined so they can be run together. So really, I'm trying to write a function of type Array (Eff e1 Unit) -> Array (Eff e2 Unit) -> Array (Eff e3 Unit)
where e3
unites all the effects of e1
and e2
.
I figured it out. For the general case, I just needed to specific that each Eff has a type that is compatiable with each other (not necessarily the same).
joinCommands :: forall e. Eff e Unit -> Eff e Unit -> Eff e Unit
joinCommands fn1 fn2 = do
fn1
fn2
For the specific case, the answer is the same. The function signature would be forall e. Array (Eff e Unit) -> Array (Eff e Unit) -> Array (Eff e Unit)
and the compiler can work out that the first set of Effs is compatible with the second set.
So if you had...
type Commands e = Array (Eff e Unit)
a :: forall e. Commands (random :: RANDOM | e)
a = []
b :: forall e. Commands (now :: NOW | e)
b = []
c :: forall e. Commands e -> Commands e -> Commands e
c = a <> b
... you can call c a b
even though a
and b
both have different explicit effects.