Open upsiflu opened 1 year ago
Current situation: We can plug Ui
s into Form.view
s by means of Ui.stateless
. They respond to Url
toggles and paths, and they distribute across screen regions, but they cannot contain other Form
s because their message type is Never
.
Rationale: The Ui
type is a tree, so subtrees can only subtype their parent. Never
is a subtype of any type. If we want to allow a nestes Ui to have a different message type, the parent would need to be parametrized over that. Notably, the only way to prevent an infinite type recursion (which is prohibited in Elm's type system), would be to swap types on each nesting:
type Ui msg1 msg2
= Swap (Ui msg2 msg1)
How elm-any-type-form
does it: It builds a linked list of accumulated types by means of Tuple (since type declarations only allow records and tuples, not lists).
tuple :
Control state1 delta1 output1
-> Control state2 delta2 output2
-> Control ( State state1, ( State state2, End ) )
( Delta delta1, ( Delta delta2, End ) )
( output1, output2 )
Advantage: Obviously, this allows states and deltas to combine arbitrarily. Disadvantage: Type signatures become hellish.
How would we implement this for the Ui
type?
At the moment, Ui
has implicit state (the Url), and msg
is hidden within the html
parameter (attribute
by default has parameter Never
):
type alias Ui region html attribute wrapper
region
: screen regions which a single view can distribute overhtml
: the output type of the Ui (akin to Control's output
)attribute
: As of now, Link
and LinkStyle
are separate, so as soon as they are combined, the link's associated element will swallow the attribute. If we want to get rid of attribute
, we need to render the link in-place, for which we'd need some sort of LinkLayout, or simply define attribute
as Html.Attribute Never
:-)wrapper
: selects how to render layout.wrap : wrapper -> html -> html
22
23