Hoisting HalogenM computation with a different slots type

Hi,

in Halogen.Query.HalogenM we have some helper functions to lift HalogenM execution from one monadic context to another: mapAction, imapState, mapOutput and hoist. What is missing is mapping between different slots type.

From my understanding it would make sense to be able to run HalogenM ... slots ... in a context of HalogenM ... slots' ... if slots row type is a subset of slots' row type:

mapSlots
  :: forall state action slots slots' output m
   . Union slots addon slots'
  => HalogenM state action slots output m
  ~> HalogenM state action slots' output m

It simply means that the computation does not use all the subcomponents available. I haven’t checked, but perhaps even unsafeCoerce would be a valid implementation of this function.

My use case is that I have a HalogenM action that uses () as slots type (for some reason I couldn’t make it compile with foralls) and I’d like to hoist this action into another HalogenM.

3 Likes

Yes, that should be safe, and unsafeCoerce would work as its implementation.

If you really wanted to, you could deconstruct the HalogenF type to prove it is safe, but you would still need to unsafeCoerce the ChildQueryBox type (which is the only part of HalogenF that references slots).

But I would be curious why you couldn’t type the component with forall slots. It should be possible. What was the error you got? Was it just a missing constraint? Was it a top-level declaration?

Hm, can’t remember now. IIRC I created an alias for a record type which had a HalogenM action inside as a field, and it didn’t typecheck in the usage site when its slots type was universally qualified inside the record. Either it’s one of the issues of “foralls don’t work well with records”, or I’m dumb. Anyway, I didn’t want to waste time playing with it, so as a quickfix I pushed the slots type as a type parameter of the alias.