AdvancedControl output state delta output
A Control
is the basic unit from which forms are composed. This library
provides various example controls and combinators that you can use to build a
form for any arbitrarily complex Elm type.
{ blank : ( State state
, Platform.Cmd.Cmd msg )
, prefill : output -> ( State state
, Platform.Cmd.Cmd msg )
, update : Delta delta -> State state -> ( State state
, Platform.Cmd.Cmd msg )
, view : State state -> Html msg
, subscriptions : State state -> Platform.Sub.Sub msg
, submit : State state -> ( State state
, Result (List Feedback) output )
}
A Form
is an interface containing functions that you can use in your
Elm Program
to initialise, view, update, subscribe, and submit your form.
sandbox : { outputToString : output -> String, control : Control state delta output } -> Platform.Program () (State state) (Delta delta)
Test and debug a Control
by turning it into a Program
that you can run as a standalone Elm application.
This is useful when you're rapidly iterating on designing a form, and you don't yet want the hassle of plumbing it into
your main Elm application's Model
and Msg
types.
Once you're happy with the form, you can then ask the Elm repl (or your editor's Elm plugin) to tell you the type
signature of the Program
, which will give you the form's State
and Delta
types. You can then plug these into your
main Model
and Msg
types wherever appropriate.
main : Program () (State String) (Delta String)
main =
sandbox
{ control = int
, outputToString = Debug.toString
}
simpleForm : { control : Control state delta output, onUpdate : Delta delta -> msg, onSubmit : msg } -> Form state delta output msg
Convert a Control
into a simple Form
, rendered as a list of controls
wrapped in an HTML <form>
element, with a submit button at the bottom.
You will need to supply a couple of variants from your app's Msg
type: one to
handle updates of the form's state, and one to handle the submission of the
form, as follows:
type alias Msg
= FormUpdated (Delta String)
| FormSubmitted
mySimpleForm : Form (State String) (Delta String) Int Msg
mySimpleForm =
form
{ control = int
, onUpdate = FormUpdated
, onSubmit = FormSubmitted
}
Now you can integrate your Form
into a larger Elm app:
mySimpleForm.blank
or mySimpleForm.prefill
in your init
function.mySimpleForm.update
in the FormUpdated
branch of your update
function.mySimpleForm.submit
in the FormSubmitted
branch of your update
function.mySimpleForm.view
in your view
function.mySimpleForm.subscriptions
in your subscriptions
function.form : { control : Control state delta output, onUpdate : Delta delta -> msg, view : List (Html msg) -> Html msg } -> Form state delta output msg
Convert a Control
into a Form
, and render the form however you like.
You will need to supply a variant from your app's Msg
type to handle updates of the form's state.
You will also need to supply a view
function that takes the List (Html msg)
produced by the
supplied Control
and returns an Html msg
, as follows:
type alias Msg
= FormUpdated (Delta String)
| FormSubmitted
myForm : Form (State String) (Delta String) Int Msg
myForm =
form
{ control = int
, onUpdate = FormUpdated
, view =
\controlView ->
H.form
[ HE.onSubmit FormSubmitted ]
(controlView ++ [ H.button [ HA.type_ "submit" ] [ H.text "Submit" ] ])
}
Now you can integrate your Form
into a larger Elm app:
myForm.blank
or myForm.prefill
in your init
function.myForm.update
in the FormUpdated
branch of your update
function.myForm.submit
in the FormSubmitted
branch of your update
function.myForm.view
in your view
function.myForm.subscriptions
in your subscriptions
function.bool : Control Basics.Bool Basics.Bool Basics.Bool
A control that produces a Bool
. Renders as an HTML checkbox.
int : Control String String Basics.Int
A control that produces an Int
. Renders as an HTML number input.
float : Control String String Basics.Float
A control that produces a Float
. Renders as an HTML number input.
string : Control String String String
A control that produces a String
. Renders as an HTML text input.
char : Control String String Char
A control that produces a Char
. Renders as an HTML text input.
enum : ( String, enum ) -> ( String, enum ) -> List ( String, enum ) -> Control enum enum enum
A control that produces a custom type where none of the variants have any payload. Renders as an HTML radio input.
type Colour
= Red
| Green
| Blue
colourControl : Control Colour Colour Colour
colourControl =
enum
( "Red", Red )
( "Green", Green )
[ ( "Blue", Blue ) ]
tuple : Control state1 delta1 output1 -> Control state2 delta2 output2 -> Control ( State state1, ( State state2, End ) ) ( Delta delta1, ( Delta delta2, End ) ) ( output1, output2 )
A combinator that produces a tuple of two controls of given types.
myTupleControl =
tuple string int
triple : Control state1 delta1 output1 -> Control state2 delta2 output2 -> Control state3 delta3 output3 -> Control ( State state1, ( State state2, ( State state3, End ) ) ) ( Delta delta1, ( Delta delta2, ( Delta delta3, End ) ) ) ( output1, output2, output3 )
A combinator that produces a triple of three controls of given types.
myTripleControl =
triple string int float
maybe : Control state delta output -> Control ( State (), ( State ( State state, End ), End ) ) ( Delta (), ( Delta ( Delta delta, End ), End ) ) (Maybe output)
A combinator that produces a Maybe
of a control of a given type.
myMaybeControl =
maybe int
result : Control failureState failureDelta failureOutput -> Control successState successDelta successOutput -> Control ( State ( State failureState, End ), ( State ( State successState, End ), End ) ) ( Delta ( Delta failureDelta, End ), ( Delta ( Delta successDelta, End ), End ) ) (Result failureOutput successOutput)
A combinator that produces a Result
with a given error and
success type.
myResultControl =
result string int
list : Control state delta output -> Control (List (State state)) (ListDelta delta) (List output)
A combinator that produces a List
of controls of a given type.
myListControl =
list int
dict : Control keyState keyDelta comparable -> Control valueState valueDelta value -> Control ( State (List (State ( State keyState, ( State valueState, End ) ))), End ) ( Delta (ListDelta ( Delta keyDelta, ( Delta valueDelta, End ) )), End ) (Dict comparable value)
A combinator that produces a Dict
from controls of given key and value
types. The key type must be comparable
.
myDictControl =
dict int string
set : Control state delta comparable -> Control ( State (List (State state)), End ) ( Delta (ListDelta delta), End ) (Set comparable)
A combinator that produces a Set
from controls of a given member
types. The member type must be comparable
.
mySetControl =
set string
array : Control state delta output -> Control ( State (List (State state)), End ) ( Delta (ListDelta delta), End ) (Array output)
A combinator that produces an Array
from a control of a given type.
myArrayControl =
array int
map : { convert : a -> b, revert : b -> a } -> Control state delta a -> Control ( State state, End ) ( Delta delta, End ) b
A combinator that converts a Control
whose output
is of type a
to a Control
whose output
is of type b
.
This is particularly useful for implementing "wrapper" types, such as Id
s.
Note: with most common map functions, such as List.map
, we only need to supply a function from a -> b
. In this case,
however, we need to supply two functions that will allow us to both convert
the type from a -> b
and
revert
it back from b -> a
.
type Id
= Id Int
idControl =
map
{ convert = \i -> Id i
, revert = \(Id i) -> i
}
int
{ blank : ( state
, Platform.Cmd.Cmd delta )
, prefill : output -> ( state
, Platform.Cmd.Cmd delta )
, update : delta -> state -> ( state
, Platform.Cmd.Cmd delta )
, view : { label : String
, id : String
, name : String
, class : String
, state : state } -> List (Html delta)
, subscriptions : state -> Platform.Sub.Sub delta
, parse : state -> Result (List String) output
, label : String
}
Configuration for a custom control. You need to supply the following fields:
blank
: an initial "empty" value for the state
of the control, plus an initial (optional) Cmd
to run. For a control whose state
is of type String
, the state value might be ""
, for a number it might be 0
.prefill
: a function that uses a value of the control's output
type to initialise the control's state
and (optionally) run an initial Cmd
. For a control that outputs an Int
, but whose state
is a String
, you might use String.fromInt
to convert the output
value into a state
value.update
: a function that updates the state
of the control based on its existing state
and a delta
type that it receives. This is exactly analogous to an Elm program's update function, where state
= Model
and delta
= Msg
.view
: a function that outputs Html delta
based on the state
of the control. This is similar to an Elm program's view function, except instead of just taking the state
as an argument, it takes a record containing the state
plus the id, name, class, and label for the input.subscriptions
: a function that outputs Sub delta
based on the state
of the control. This is exactly analogous to an Elm program's subscriptions function.parse
: a function that attempts to parse the control's state into its output type, producing a result. If parsing fails, it can provide a list of errors.create : ControlConfig state delta output -> Control state delta output
Create a simple control, with any arbitrary state
and delta
types, and
producing any arbitrary output
type.
Here's how we could create a control like the famous counter example from the Elm Guide
type CounterDelta
= Increment
| Decrement
counterControl : Control Int CounterDelta Int
counterControl =
create
{ blank = 0
, prefill = identity
, update =
\delta state ->
case delta of
Increment ->
state + 1
Decrement ->
state - 1
, view =
\{ state, name, id, label, class } ->
Html.div [ Html.Attributes.class class ]
[ Html.label
[ Html.Attributes.for id ]
[ Html.text label ]
, Html.div
[ Html.Attributes.id id
, Html.Attributes.name name
]
[ Html.button
[ Html.Attributes.type_ "button"
, Html.Events.onClick Increment
]
[ Html.text "+" ]
, Html.div [] [ Html.text <| String.fromInt state ]
, Html.button
[ Html.Attributes.type_ "button"
, Html.Events.onClick Decrement
]
[ Html.text "-" ]
]
]
, subscriptions = \state -> Sub.none
, parse = Ok
}
failIf : (output -> Basics.Bool) -> String -> Control state delta output -> Control state delta output
Display an error on a Control
if its output fails to meet the predicate.
This causes the Control
to fail validation.
positiveInt =
int
|> failIf
(\x -> x < 1)
"This must be greater than zero!"
noteIf : (output -> Basics.Bool) -> String -> Control state delta output -> Control state delta output
Display an note on a Control
if its output fails to meet the predicate.
This just shows the user a message - it doesn't cause the Control
to fail
validation.
positiveInt =
int
|> noteIf
(\x -> x < 1)
"Should this be greater than zero?"
You may want display errors on one or more controls based on the validation of another control higher up the tree.
Take the example of a password creation form. You want to validate that the "Enter password" and "Confirm password" fields both contain the same string, and show a helpful error message on the "Confirm password" field if they don't. You can achieve this as follows:
passwordControl =
record
(\password confirmation ->
{ password = password
, confirmation = confirmation
}
)
|> field string
|> field
(string
|> respond
{ alert = "passwords-do-not-match"
, fail = True
, message = "Must match 'Enter password' field"
}
)
|> endRecord
|> alertIf
(\{ password, confirmation } ->
password /= confirmation
)
"passwords-do-not-match"
alertIf : (output -> Basics.Bool) -> String -> Control state delta output -> Control state delta output
Emit an alert from a Control
if its output fails to meet the predicate.
This is meant to be used in combination with respond
, which listens for the
alert and displays an error or notification message on the appropriate
control(s).
respond : { alert : String, fail : Basics.Bool, message : String } -> Control state delta output -> Control state delta output
Respond to an alert emitted by another Control
, display an error or
notification message on this control, and if desired, cause validation to fail.
This is meant to be used in combination with alertIf
, which emits the alert.
alertAtIndexes : (output -> List Basics.Int) -> String -> Control (List state) (ListDelta delta) output -> Control (List state) (ListDelta delta) output
Conditionally display an error on one or more items in a list
control,
based on the output of the list
control.
The following example will display errors on the first two items in a list of strings, if and only if those first two items are "hello" and "world":
myString =
string
|> catch
{ alert = "no-hello-world"
, fail = True
, message = "The first two items in the list must not be \"hello\" and \"world\"."
}
myList =
list myString
|> alertAtIndexes
(\list_ ->
case list of
"hello" :: "world" :: _ ->
[ 0, 1 ]
_ ->
[]
)
"no-hello-world"
default : input -> AdvancedControl input state delta output -> AdvancedControl input state delta output
Set a default output
value for a Control
.
oneAndHello =
tuple int string
|> default ( 1, "hello" )
debounce : Basics.Float -> Control state delta output -> Control state delta output
Debounce a Control
for a number of milliseconds before it will display
any parsing or validation errors. This can be used to allow the user to finish
typing into a text input before we show them feedback.
sluggishStringControl =
string
|> debounce 2000
id : String -> Control state delta output -> Control state delta output
Set an id for a Control
.
myStringControlHasAnId =
string
|> id "my-string"
name : String -> Control state delta output -> Control state delta output
Set a name for a Control
.
myStringControlHasAName =
string
|> name "My string"
label : String -> AdvancedControl input state delta output -> AdvancedControl input state delta output
Set a label for a Control
.
myStringControlHasALabel =
string
|> label "Enter your name"
class : String -> Control state delta output -> Control state delta output
Add an HTML class attribute for a Control
. See docs for Html.Attributes.class in elm-html.
myStringControlHasAClass =
string
|> class "important"
|> class "no-really"
classList : List ( String, Basics.Bool ) -> Control state delta output -> Control state delta output
Add a list of HTML class attributes to a Control
. See docs for Html.Attributes.classList in the elm/html
package.
myStringControlHasClasses =
string
|> classList
[ ( "important", True )
, ( "no-really", True )
, ( "ignore-me", False )
]
wrapView : (List (Html (Delta delta)) -> List (Html (Delta delta))) -> Control state delta output -> Control state delta output
Transform the HTML output of a Control
's view function.
wrappedInt =
int
|> wrapView (\view -> [ Html.div [] view ])
A data structure used to build records
record : toOutput -> RecordBuilder End End (a12 -> a12) (a11 -> a11) (a10 -> a10) (a9 -> a9) (a8 -> a8) (a7 -> a7) (b -> c -> c) (a6 -> a6) (d -> e -> e) (f -> g -> g) (a5 -> a5) (a4 -> a4) (a3 -> a3) (a2 -> a2) toOutput (a1 -> a1) (a -> a)
A combinator that produces a record type, or any 'product' type that needs to
be constructed from multiple controls. (For example, the tuple
combinator in
this library is built using the record
combinator).
type alias MyRecord =
{ name : String
, age : Int
}
myRecordControl =
record
(\name age ->
{ name = name
, age = age
}
)
|> field string
|> field int
|> endRecord
field : (recordOutput8 -> output7) -> AdvancedControl input8 state9 delta12 output7 -> RecordBuilder after1 afters1 (( Delta delta13, a18 ) -> c5) (( ( Delta delta13, a18 ) -> c5, a17 ) -> c4) (a16 -> List Alert -> restFns7 -> restStates7 -> List Alert) (a15 -> List (Platform.Cmd.Cmd delta1_1) -> restDeltaSetters2 -> restDeltas2 -> List (Platform.Cmd.Cmd delta1_1)) (a14 -> List Alert -> List Feedback -> restFns6 -> restStates6 -> List Feedback) (a13 -> List Alert -> restFns5 -> restStates5 -> List Alert) (Path -> ( RecordFns input8 state9 delta12 output7 recordOutput8, a12 ) -> c3) (a11 -> restFns4 -> restStates4 -> restStates4) (Path -> ( Platform.Cmd.Cmd (Delta delta12), a10 ) -> c2) (Path -> ( State state9, a9 ) -> c1) (a8 -> (a7 -> c) -> List (Platform.Cmd.Cmd msg1) -> a5 -> b -> d -> e) (a4 -> befores -> afters -> next) (a3 -> Result (List Feedback) output1_1 -> restFns3 -> restStates3 -> Result (List Feedback) output2_1) (a2 -> List (Platform.Sub.Sub msg) -> restDeltas1 -> restFns2 -> restStates2 -> List (Platform.Sub.Sub msg)) toOutput (a1 -> { newCmds : List (Platform.Cmd.Cmd recordDelta1), newStates : restStates1 -> recordState0 } -> restFns1 -> restDeltaSetters1 -> restDeltas -> restStates1 -> { newCmds : List (Platform.Cmd.Cmd recordDelta1), newStates : recordState }) (a -> List (Subcontrol recordDelta) -> List Alert -> restFns -> restDeltaSetters -> restStates -> List (Subcontrol recordDelta)) -> RecordBuilder ( Delta delta11, after1 ) ( after1, afters1 ) (a18 -> c5) (a17 -> c4) (a16 -> List Alert -> ( RecordFns input7 state8 delta10 output6 recordOutput7, restFns7 ) -> ( State state8, restStates7 ) -> List Alert) (a15 -> List (Platform.Cmd.Cmd delta1_1) -> ( delta9 -> delta1_1, restDeltaSetters2 ) -> ( Platform.Cmd.Cmd delta9, restDeltas2 ) -> List (Platform.Cmd.Cmd delta1_1)) (a14 -> List Alert -> List Feedback -> ( RecordFns input6 state7 delta8 output5 recordOutput6, restFns6 ) -> ( State state7, restStates6 ) -> List Feedback) (a13 -> List Alert -> ( RecordFns input5 state6 delta7 output4 recordOutput5, restFns5 ) -> ( State state6, restStates5 ) -> List Alert) (Path -> a12 -> c3) (a11 -> ( RecordFns input4 state5 delta6 output3 recordOutput4, restFns4 ) -> ( State state5, restStates4 ) -> ( State state5, restStates4 )) (Path -> a10 -> c2) (Path -> a9 -> c1) (a8 -> (( State state4, a7 ) -> c) -> List (Platform.Cmd.Cmd msg1) -> a5 -> ( RecordFns a6 state4 delta5 a6 a5, b ) -> ( Delta delta5 -> msg1, d ) -> e) (a4 -> ( ( value, after ) -> delta4, befores ) -> ( after, afters ) -> ( value -> delta4, next )) (a3 -> Result (List Feedback) (output0 -> output1_1) -> ( RecordFns input3 state3 delta3 output0 recordOutput3, restFns3 ) -> ( State state3, restStates3 ) -> Result (List Feedback) output2_1) (a2 -> List (Platform.Sub.Sub msg) -> ( Delta delta2 -> msg, restDeltas1 ) -> ( RecordFns input2 state2 delta2 output2 recordOutput2, restFns2 ) -> ( State state2, restStates2 ) -> List (Platform.Sub.Sub msg)) toOutput (a1 -> { newCmds : List (Platform.Cmd.Cmd recordDelta1), newStates : ( State state1, restStates1 ) -> recordState0 } -> ( RecordFns input1 state1 delta1 output1 recordOutput1, restFns1 ) -> ( Delta delta1 -> recordDelta1, restDeltaSetters1 ) -> ( Delta delta1, restDeltas ) -> ( State state1, restStates1 ) -> { newCmds : List (Platform.Cmd.Cmd recordDelta1), newStates : recordState }) (a -> List (Subcontrol recordDelta) -> List Alert -> ( RecordFns input state delta output recordOutput, restFns ) -> ( Delta delta -> recordDelta, restDeltaSetters ) -> ( State state, restStates ) -> List (Subcontrol recordDelta))
Add a field to a record
combinator.
type alias Hello =
{ hello : String }
helloControl =
record Hello
|> field string
|> endRecord
endRecord : RecordBuilder after afters before (End -> befores) ((List Alert -> End -> End -> List Alert) -> List Alert -> ( RecordFns input1 state delta output1 recordInput, restFns ) -> ( State state, restStates ) -> List Alert) ((List (Platform.Cmd.Cmd ( Delta delta, restDeltas )) -> End -> End -> List (Platform.Cmd.Cmd ( Delta delta, restDeltas ))) -> List (Platform.Cmd.Cmd ( Delta delta, restDeltas )) -> ( Delta delta -> recordDelta, restSetters ) -> deltas -> List (Platform.Cmd.Cmd ( Delta delta, restDeltas ))) ((List Alert -> List Feedback -> End -> End -> List Feedback) -> List Alert -> List Feedback -> ( RecordFns input1 state delta output1 recordInput, restFns ) -> ( State state, restStates ) -> List Feedback) ((List Alert -> End -> End -> List Alert) -> List Alert -> ( RecordFns input1 state delta output1 recordInput, restFns ) -> ( State state, restStates ) -> List Alert) (Path -> End -> ( RecordFns input1 state delta output1 recordInput, restFns )) ((End -> End -> End) -> ( RecordFns input1 state delta output1 recordInput, restFns ) -> ( State state, restStates ) -> ( State state, restStates )) (Path -> End -> deltas) (Path -> End -> ( State state, restStates )) (((End -> state1) -> List (Platform.Cmd.Cmd msg) -> b -> End -> End -> ( State state1, Platform.Cmd.Cmd (Delta msg) )) -> (a -> a) -> List c -> input -> ( RecordFns input1 state delta output1 recordInput, restFns ) -> ( Delta delta -> recordDelta, restSetters ) -> ( State ( State state, restStates ), Platform.Cmd.Cmd (Delta ( Delta delta, restDeltas )) )) ((End -> End -> End) -> befores -> afters -> ( Delta delta -> recordDelta, restSetters )) ((Result (List Feedback) output -> End -> End -> Result (List Feedback) output) -> Result (List Feedback) output1_1 -> ( RecordFns input1 state delta output1 recordInput, restFns ) -> ( State state, restStates ) -> Result (List Feedback) output) ((List (Platform.Sub.Sub ( Delta delta, restDeltas )) -> End -> End -> End -> List (Platform.Sub.Sub ( Delta delta, restDeltas ))) -> List (Platform.Sub.Sub ( Delta delta, restDeltas )) -> ( Delta delta -> recordDelta, restSetters ) -> ( RecordFns input1 state delta output1 recordInput, restFns ) -> ( State state, restStates ) -> List (Platform.Sub.Sub ( Delta delta, restDeltas ))) output1_1 (({ newCmds : List (Platform.Cmd.Cmd ( Delta delta, restDeltas )), newStates : End -> ( State state, restStates ) } -> End -> End -> End -> End -> { newCmds : List (Platform.Cmd.Cmd ( Delta delta, restDeltas )), newStates : End -> ( State state, restStates ) }) -> { newCmds : List (Platform.Cmd.Cmd ( Delta delta, restDeltas )), newStates : ( State state, restStates ) -> ( State state, restStates ) } -> ( RecordFns input1 state delta output1 recordInput, restFns ) -> ( Delta delta -> recordDelta, restSetters ) -> ( Delta delta, restDeltas ) -> ( State state, restStates ) -> { newCmds : List (Platform.Cmd.Cmd ( Delta delta, restDeltas )), newStates : End -> ( State state, restStates ) }) ((List (Subcontrol ( Delta delta, restDeltas )) -> List Alert -> End -> End -> End -> List (Subcontrol ( Delta delta, restDeltas ))) -> List (Subcontrol ( Delta delta, restDeltas )) -> List Alert -> ( RecordFns input1 state delta output1 recordInput, restFns ) -> ( Delta delta -> recordDelta, restSetters ) -> ( State state, restStates ) -> List (Subcontrol ( Delta delta, restDeltas ))) -> AdvancedControl input ( State state, restStates ) ( Delta delta, restDeltas ) output
Finalise the construction of a record
combinator.
type alias Hello =
{ hello : String }
helloControl =
record Hello
|> field string
|> endRecord
{ selected : Basics.Int
, selectMsg : Basics.Int -> Delta delta
, id : String
, label : String
, class : String
}
Configuration for the layout
function
{ html : List (Html (Delta delta))
, label : String
, index : Basics.Int
}
Data used by the layout
function to render a subcontrol of a combinator.
layout : (LayoutConfig delta -> List (Subcontrol delta) -> List (Html (Delta delta))) -> Control state delta output -> Control state delta output
Define the HTML output for a combinator.
This is useful if you want to alter the way that the combinator's subcontrols are laid out on the screen.
For example, you could use it to present a record control as a wizard, rather than a list. The wizard example below is very naive, but hopefully gives you the idea.
type alias MyRecord =
{ name : String
, age : Int
}
myRecordControl =
record
(\name age ->
{ name = name
, age = age
}
)
|> field string
|> field int
|> endRecord
|> layout wizard
wizard config subcontrols =
let
currentPage =
config.selected
totalPages =
List.length subcontrols
currentPageView =
subcontrols
|> List.filter (\{ index } -> index == currentPage)
|> List.map .html
|> List.concat
nextClicked =
config.selectMsg (currentPage + 1)
backClicked =
config.selectMsg (currentPage - 1)
navigationButton txt msg =
Html.button
[ Html.Attributes.type_ "button"
, Html.Events.onClick msg
]
[ Html.text txt ]
in
Html.div
[ Html.Attributes.id config.id
, Html.Attributes.class config.class
]
([ Html.h1 [] [ Html.text "Wizard!" ]
, navigationButton "Back" backClicked
, Html.text
(String.join " "
[ "page"
, String.fromInt currentPage
, "of"
, String.fromInt totalPages
]
)
, navigationButton "Next" nextClicked
]
++ currentPageView
)
A data structure used to build custom types
customType : destructor -> CustomTypeBuilder (applyInputs -> applyInputs) (debouncingReceiverCollector -> debouncingReceiverCollector) End End (deltaBefore -> deltaBefore) (deltaBefores -> deltaBefores) destructor (errorCollector -> errorCollector) (alertEmitter -> alertEmitter) (Path -> fns -> fns) (idleSetter -> idleSetter) (Path -> initialDeltas -> initialDeltas) (Path -> initialStates -> initialStates) (initialiseDeltas -> initialiseDeltas) (makeDeltaSetters -> makeDeltaSetters) (makeStateSetters -> makeStateSetters) (parser -> parser) End End (stateBefore -> stateBefore) (stateBefores -> stateBefores) (stateInserter -> stateInserter) (subscriptionCollector -> subscriptionCollector) (toArgStates -> toArgStates) (updater -> updater) (viewer -> viewer)
A combinator that produces a custom type.
type MyCustomType
= NoArgs
| OneArg String
| TwoArgs Int Float
myCustomTypeControl =
customType
(\noArgs oneArg twoArgs tag ->
case tag of
NoArgs ->
noArgs
OneArg arg1 ->
oneArg arg1
TwoArgs arg1 arg2 ->
TwoArgs arg1 arg2
)
|> tag0 "NoArgs" NoArgs
|> tag1 "OneArg" OneArg string
|> tag2 "TwoArgs" TwoArgs int float
|> endCustomType
tag0 : String -> output9 -> CustomTypeBuilder (a21 -> destructor1 -> restInputToStateConverters -> tag -> ( State tagStates2, Platform.Cmd.Cmd delta12 )) (a20 -> List Alert -> restFns7 -> restStates8 -> List Alert) deltaAfter deltaAfters (( Delta delta14, a19 ) -> c7) (( ( Delta delta14, a19 ) -> c7, a18 ) -> c6) destructor (a17 -> List Alert -> List Feedback -> restFns6 -> restStates7 -> List Feedback) (a16 -> List Alert -> Basics.Int -> restFns5 -> restStates6 -> List Alert) (Path -> ( ControlFns output9 () () output9, a15 ) -> c5) (a14 -> Basics.Int -> restFns4 -> restStates5 -> restStates5) (Path -> ( Platform.Cmd.Cmd (Delta ()), a13 ) -> c4) (Path -> ( State (), a12 ) -> c3) (a11 -> List (Platform.Cmd.Cmd delta1_2) -> restDeltaSetters2 -> restDeltas1 -> List (Platform.Cmd.Cmd delta1_2)) (a10 -> befores -> afters -> next) (a9 -> { controlFns : restControlFns, deltaSetters : restDeltaSetters1, finalTagStates : nextFinalTagState -> restFinalTagStates, initialTagStates : ( State state4, restStates4 ), inputTuplizers : restInputTuplizers, maybeOverridesAfter : restMaybeOverridesAfter, maybeOverridesBefore : restMaybeOverridesBefore, tagStateOverrider : (Basics.Int -> Basics.Int -> (End -> tagStates1) -> End -> End -> State tagStates1) -> Basics.Int -> Basics.Int -> (identity -> identity) -> ( Maybe (State state4), restMaybeStates ) -> ( State state4, restStates4 ) -> State tagStates1 } -> toFinalTagStates) (a8 -> Result (List Feedback) output3 -> Basics.Int -> restFns3 -> restStates3 -> Result (List Feedback) output3) stateAfter stateAfters (( Maybe a23, a6 ) -> c2) (( ( Maybe a23, a6 ) -> c2, a5 ) -> c1) (a4 -> Basics.Int -> Basics.Int -> (restArgStates -> tagStates) -> restMaybeArgStates -> restArgStates -> State tagStates) (a3 -> List (Platform.Sub.Sub delta1_1) -> restSetters1 -> restFns2 -> restStates2 -> List (Platform.Sub.Sub delta1_1)) (( (output9 -> b) -> b, a2 ) -> c) (a1 -> { newCmds : List (Platform.Cmd.Cmd recordDelta), newStates : restStates1 -> recordState0 } -> restFns1 -> restDeltaSetters -> restDeltas -> restStates1 -> { newCmds : List (Platform.Cmd.Cmd recordDelta), newStates : recordState }) (a -> List (Subcontrol delta) -> List Alert -> restFns -> restSetters -> restStates -> List (Subcontrol delta)) -> CustomTypeBuilder (a21 -> (inputToStateConverter -> destructor1) -> ( inputToStateConverter, restInputToStateConverters ) -> tag -> ( State tagStates2, Platform.Cmd.Cmd delta12 )) (a20 -> List Alert -> ( ControlFns input8 state8 delta11 output8, restFns7 ) -> ( State state8, restStates8 ) -> List Alert) ( Delta delta10, deltaAfter ) ( deltaAfter, deltaAfters ) (a19 -> c7) (a18 -> c6) destructor (a17 -> List Alert -> List Feedback -> ( ControlFns input7 state7 delta9 output7, restFns6 ) -> ( State state7, restStates7 ) -> List Feedback) (a16 -> List Alert -> Basics.Int -> ( ControlFns input6 state6 delta8 output6, restFns5 ) -> ( State state6, restStates6 ) -> List Alert) (Path -> a15 -> c5) (a14 -> Basics.Int -> ( ControlFns input5 state5 delta7 output5, restFns4 ) -> ( State state5, restStates5 ) -> ( State state5, restStates5 )) (Path -> a13 -> c4) (Path -> a12 -> c3) (a11 -> List (Platform.Cmd.Cmd delta1_2) -> ( delta6 -> delta1_2, restDeltaSetters2 ) -> ( Platform.Cmd.Cmd delta6, restDeltas1 ) -> List (Platform.Cmd.Cmd delta1_2)) (a10 -> ( ( value, after ) -> delta5, befores ) -> ( after, afters ) -> ( value -> delta5, next )) (a9 -> { controlFns : ( ControlFns input4 state1_1 delta4 output4, restControlFns ), deltaSetters : ( Delta delta4 -> tagDelta, restDeltaSetters1 ), finalTagStates : ( finalTagState, nextFinalTagState ) -> restFinalTagStates, initialTagStates : ( State state4, restStates4 ), inputTuplizers : ( (input4 -> ( State tagStates1, Platform.Cmd.Cmd (Delta tagDelta) )) -> finalTagState, restInputTuplizers ), maybeOverridesAfter : ( maybeOverrideAfter, restMaybeOverridesAfter ), maybeOverridesBefore : ( ( Maybe (State state1_1), maybeOverrideAfter ) -> ( Maybe (State state4), restMaybeStates ), restMaybeOverridesBefore ), tagStateOverrider : (Basics.Int -> Basics.Int -> (End -> tagStates1) -> End -> End -> State tagStates1) -> Basics.Int -> Basics.Int -> (identity -> identity) -> ( Maybe (State state4), restMaybeStates ) -> ( State state4, restStates4 ) -> State tagStates1 } -> toFinalTagStates) (a8 -> Result (List Feedback) output3 -> Basics.Int -> ( ControlFns input3 state3 delta3 output3, restFns3 ) -> ( State state3, restStates3 ) -> Result (List Feedback) output3) ( Maybe a7, stateAfter ) ( stateAfter, stateAfters ) (a6 -> c2) (a5 -> c1) (a4 -> Basics.Int -> Basics.Int -> (( State argState, restArgStates ) -> tagStates) -> ( Maybe (State argState), restMaybeArgStates ) -> ( State argState, restArgStates ) -> State tagStates) (a3 -> List (Platform.Sub.Sub delta1_1) -> ( Delta delta2 -> delta1_1, restSetters1 ) -> ( ControlFns input2 state2 delta2 output2, restFns2 ) -> ( State state2, restStates2 ) -> List (Platform.Sub.Sub delta1_1)) (a2 -> c) (a1 -> { newCmds : List (Platform.Cmd.Cmd recordDelta), newStates : ( State state1, restStates1 ) -> recordState0 } -> ( ControlFns input1 state1 delta1 output1, restFns1 ) -> ( Delta delta1 -> recordDelta, restDeltaSetters ) -> ( Delta delta1, restDeltas ) -> ( State state1, restStates1 ) -> { newCmds : List (Platform.Cmd.Cmd recordDelta), newStates : recordState }) (a -> List (Subcontrol delta) -> List Alert -> ( ControlFns input state e output, restFns ) -> ( Delta e -> delta, restSetters ) -> ( State state, restStates ) -> List (Subcontrol delta))
Add a tag with no arguments to a custom type.
type Unit
= Unit
unitControl =
customType
(\unit tag ->
case tag of
Unit ->
unit
)
|> tag0 "Unit" Unit
|> endCustomType
tag1 : String -> (output10 -> output9) -> AdvancedControl output10 state9 delta13 output10 -> CustomTypeBuilder (a21 -> destructor1 -> restInputToStateConverters -> tag -> ( State tagStates2, Platform.Cmd.Cmd delta12 )) (a20 -> List Alert -> restFns7 -> restStates8 -> List Alert) deltaAfter deltaAfters (( Delta delta14, a19 ) -> c7) (( ( Delta delta14, a19 ) -> c7, a18 ) -> c6) destructor (a17 -> List Alert -> List Feedback -> restFns6 -> restStates7 -> List Feedback) (a16 -> List Alert -> Basics.Int -> restFns5 -> restStates6 -> List Alert) (Path -> ( ControlFns ( output10, b ) ( State state9, End ) ( Delta delta13, End ) output9, a15 ) -> c5) (a14 -> Basics.Int -> restFns4 -> restStates5 -> restStates5) (Path -> ( Platform.Cmd.Cmd (Delta ( Delta delta13, End )), a13 ) -> c4) (Path -> ( State ( State state9, End ), a12 ) -> c3) (a11 -> List (Platform.Cmd.Cmd delta1_2) -> restDeltaSetters2 -> restDeltas1 -> List (Platform.Cmd.Cmd delta1_2)) (a10 -> befores -> afters -> next) (a9 -> { controlFns : restControlFns, deltaSetters : restDeltaSetters1, finalTagStates : nextFinalTagState -> restFinalTagStates, initialTagStates : ( State state4, restStates4 ), inputTuplizers : restInputTuplizers, maybeOverridesAfter : restMaybeOverridesAfter, maybeOverridesBefore : restMaybeOverridesBefore, tagStateOverrider : (Basics.Int -> Basics.Int -> (End -> tagStates1) -> End -> End -> State tagStates1) -> Basics.Int -> Basics.Int -> (identity -> identity) -> ( Maybe (State state4), restMaybeStates ) -> ( State state4, restStates4 ) -> State tagStates1 } -> toFinalTagStates) (a8 -> Result (List Feedback) output3 -> Basics.Int -> restFns3 -> restStates3 -> Result (List Feedback) output3) stateAfter stateAfters (( Maybe a23, a6 ) -> c2) (( ( Maybe a23, a6 ) -> c2, a5 ) -> c1) (a4 -> Basics.Int -> Basics.Int -> (restArgStates -> tagStates) -> restMaybeArgStates -> restArgStates -> State tagStates) (a3 -> List (Platform.Sub.Sub delta1_1) -> restSetters1 -> restFns2 -> restStates2 -> List (Platform.Sub.Sub delta1_1)) (( (( d, End ) -> f) -> d -> f, a2 ) -> c) (a1 -> { newCmds : List (Platform.Cmd.Cmd recordDelta), newStates : restStates1 -> recordState0 } -> restFns1 -> restDeltaSetters -> restDeltas -> restStates1 -> { newCmds : List (Platform.Cmd.Cmd recordDelta), newStates : recordState }) (a -> List (Subcontrol delta) -> List Alert -> restFns -> restSetters -> restStates -> List (Subcontrol delta)) -> CustomTypeBuilder (a21 -> (inputToStateConverter -> destructor1) -> ( inputToStateConverter, restInputToStateConverters ) -> tag -> ( State tagStates2, Platform.Cmd.Cmd delta12 )) (a20 -> List Alert -> ( ControlFns input8 state8 delta11 output8, restFns7 ) -> ( State state8, restStates8 ) -> List Alert) ( Delta delta10, deltaAfter ) ( deltaAfter, deltaAfters ) (a19 -> c7) (a18 -> c6) destructor (a17 -> List Alert -> List Feedback -> ( ControlFns input7 state7 delta9 output7, restFns6 ) -> ( State state7, restStates7 ) -> List Feedback) (a16 -> List Alert -> Basics.Int -> ( ControlFns input6 state6 delta8 output6, restFns5 ) -> ( State state6, restStates6 ) -> List Alert) (Path -> a15 -> c5) (a14 -> Basics.Int -> ( ControlFns input5 state5 delta7 output5, restFns4 ) -> ( State state5, restStates5 ) -> ( State state5, restStates5 )) (Path -> a13 -> c4) (Path -> a12 -> c3) (a11 -> List (Platform.Cmd.Cmd delta1_2) -> ( delta6 -> delta1_2, restDeltaSetters2 ) -> ( Platform.Cmd.Cmd delta6, restDeltas1 ) -> List (Platform.Cmd.Cmd delta1_2)) (a10 -> ( ( value, after ) -> delta5, befores ) -> ( after, afters ) -> ( value -> delta5, next )) (a9 -> { controlFns : ( ControlFns input4 state1_1 delta4 output4, restControlFns ), deltaSetters : ( Delta delta4 -> tagDelta, restDeltaSetters1 ), finalTagStates : ( finalTagState, nextFinalTagState ) -> restFinalTagStates, initialTagStates : ( State state4, restStates4 ), inputTuplizers : ( (input4 -> ( State tagStates1, Platform.Cmd.Cmd (Delta tagDelta) )) -> finalTagState, restInputTuplizers ), maybeOverridesAfter : ( maybeOverrideAfter, restMaybeOverridesAfter ), maybeOverridesBefore : ( ( Maybe (State state1_1), maybeOverrideAfter ) -> ( Maybe (State state4), restMaybeStates ), restMaybeOverridesBefore ), tagStateOverrider : (Basics.Int -> Basics.Int -> (End -> tagStates1) -> End -> End -> State tagStates1) -> Basics.Int -> Basics.Int -> (identity -> identity) -> ( Maybe (State state4), restMaybeStates ) -> ( State state4, restStates4 ) -> State tagStates1 } -> toFinalTagStates) (a8 -> Result (List Feedback) output3 -> Basics.Int -> ( ControlFns input3 state3 delta3 output3, restFns3 ) -> ( State state3, restStates3 ) -> Result (List Feedback) output3) ( Maybe a7, stateAfter ) ( stateAfter, stateAfters ) (a6 -> c2) (a5 -> c1) (a4 -> Basics.Int -> Basics.Int -> (( State argState, restArgStates ) -> tagStates) -> ( Maybe (State argState), restMaybeArgStates ) -> ( State argState, restArgStates ) -> State tagStates) (a3 -> List (Platform.Sub.Sub delta1_1) -> ( Delta delta2 -> delta1_1, restSetters1 ) -> ( ControlFns input2 state2 delta2 output2, restFns2 ) -> ( State state2, restStates2 ) -> List (Platform.Sub.Sub delta1_1)) (a2 -> c) (a1 -> { newCmds : List (Platform.Cmd.Cmd recordDelta), newStates : ( State state1, restStates1 ) -> recordState0 } -> ( ControlFns input1 state1 delta1 output1, restFns1 ) -> ( Delta delta1 -> recordDelta, restDeltaSetters ) -> ( Delta delta1, restDeltas ) -> ( State state1, restStates1 ) -> { newCmds : List (Platform.Cmd.Cmd recordDelta), newStates : recordState }) (a -> List (Subcontrol delta) -> List Alert -> ( ControlFns input state e output, restFns ) -> ( Delta e -> delta, restSetters ) -> ( State state, restStates ) -> List (Subcontrol delta))
Add a tag with one argument to a custom type.
type alias MyResult =
Result String Int
myResultControl =
customType
(\ok err tag ->
case tag of
Ok value ->
ok value
Err error ->
err error
)
|> tag1 "Ok" Ok int
|> tag1 "Err" Err string
|> endCustomType
tag2 : String -> (output11 -> output10 -> output9) -> AdvancedControl output11 state10 delta14 output11 -> AdvancedControl output10 state9 delta13 output10 -> CustomTypeBuilder (a21 -> destructor1 -> restInputToStateConverters -> tag -> ( State tagStates2, Platform.Cmd.Cmd delta12 )) (a20 -> List Alert -> restFns7 -> restStates8 -> List Alert) deltaAfter deltaAfters (( Delta delta14_1, a19 ) -> c7) (( ( Delta delta14_1, a19 ) -> c7, a18 ) -> c6) destructor (a17 -> List Alert -> List Feedback -> restFns6 -> restStates7 -> List Feedback) (a16 -> List Alert -> Basics.Int -> restFns5 -> restStates6 -> List Alert) (Path -> ( ControlFns ( output11, ( output10, b ) ) ( State state10, ( State state9, End ) ) ( Delta delta14, ( Delta delta13, End ) ) output9, a15 ) -> c5) (a14 -> Basics.Int -> restFns4 -> restStates5 -> restStates5) (Path -> ( Platform.Cmd.Cmd (Delta ( Delta delta14, ( Delta delta13, End ) )), a13 ) -> c4) (Path -> ( State ( State state10, ( State state9, End ) ), a12 ) -> c3) (a11 -> List (Platform.Cmd.Cmd delta1_2) -> restDeltaSetters2 -> restDeltas1 -> List (Platform.Cmd.Cmd delta1_2)) (a10 -> befores -> afters -> next) (a9 -> { controlFns : restControlFns, deltaSetters : restDeltaSetters1, finalTagStates : nextFinalTagState -> restFinalTagStates, initialTagStates : ( State state4, restStates4 ), inputTuplizers : restInputTuplizers, maybeOverridesAfter : restMaybeOverridesAfter, maybeOverridesBefore : restMaybeOverridesBefore, tagStateOverrider : (Basics.Int -> Basics.Int -> (End -> tagStates1) -> End -> End -> State tagStates1) -> Basics.Int -> Basics.Int -> (identity -> identity) -> ( Maybe (State state4), restMaybeStates ) -> ( State state4, restStates4 ) -> State tagStates1 } -> toFinalTagStates) (a8 -> Result (List Feedback) output3 -> Basics.Int -> restFns3 -> restStates3 -> Result (List Feedback) output3) stateAfter stateAfters (( Maybe a23, a6 ) -> c2) (( ( Maybe a23, a6 ) -> c2, a5 ) -> c1) (a4 -> Basics.Int -> Basics.Int -> (restArgStates -> tagStates) -> restMaybeArgStates -> restArgStates -> State tagStates) (a3 -> List (Platform.Sub.Sub delta1_1) -> restSetters1 -> restFns2 -> restStates2 -> List (Platform.Sub.Sub delta1_1)) (( (( d, ( f, End ) ) -> g) -> d -> f -> g, a2 ) -> c) (a1 -> { newCmds : List (Platform.Cmd.Cmd recordDelta), newStates : restStates1 -> recordState0 } -> restFns1 -> restDeltaSetters -> restDeltas -> restStates1 -> { newCmds : List (Platform.Cmd.Cmd recordDelta), newStates : recordState }) (a -> List (Subcontrol delta) -> List Alert -> restFns -> restSetters -> restStates -> List (Subcontrol delta)) -> CustomTypeBuilder (a21 -> (inputToStateConverter -> destructor1) -> ( inputToStateConverter, restInputToStateConverters ) -> tag -> ( State tagStates2, Platform.Cmd.Cmd delta12 )) (a20 -> List Alert -> ( ControlFns input8 state8 delta11 output8, restFns7 ) -> ( State state8, restStates8 ) -> List Alert) ( Delta delta10, deltaAfter ) ( deltaAfter, deltaAfters ) (a19 -> c7) (a18 -> c6) destructor (a17 -> List Alert -> List Feedback -> ( ControlFns input7 state7 delta9 output7, restFns6 ) -> ( State state7, restStates7 ) -> List Feedback) (a16 -> List Alert -> Basics.Int -> ( ControlFns input6 state6 delta8 output6, restFns5 ) -> ( State state6, restStates6 ) -> List Alert) (Path -> a15 -> c5) (a14 -> Basics.Int -> ( ControlFns input5 state5 delta7 output5, restFns4 ) -> ( State state5, restStates5 ) -> ( State state5, restStates5 )) (Path -> a13 -> c4) (Path -> a12 -> c3) (a11 -> List (Platform.Cmd.Cmd delta1_2) -> ( delta6 -> delta1_2, restDeltaSetters2 ) -> ( Platform.Cmd.Cmd delta6, restDeltas1 ) -> List (Platform.Cmd.Cmd delta1_2)) (a10 -> ( ( value, after ) -> delta5, befores ) -> ( after, afters ) -> ( value -> delta5, next )) (a9 -> { controlFns : ( ControlFns input4 state1_1 delta4 output4, restControlFns ), deltaSetters : ( Delta delta4 -> tagDelta, restDeltaSetters1 ), finalTagStates : ( finalTagState, nextFinalTagState ) -> restFinalTagStates, initialTagStates : ( State state4, restStates4 ), inputTuplizers : ( (input4 -> ( State tagStates1, Platform.Cmd.Cmd (Delta tagDelta) )) -> finalTagState, restInputTuplizers ), maybeOverridesAfter : ( maybeOverrideAfter, restMaybeOverridesAfter ), maybeOverridesBefore : ( ( Maybe (State state1_1), maybeOverrideAfter ) -> ( Maybe (State state4), restMaybeStates ), restMaybeOverridesBefore ), tagStateOverrider : (Basics.Int -> Basics.Int -> (End -> tagStates1) -> End -> End -> State tagStates1) -> Basics.Int -> Basics.Int -> (identity -> identity) -> ( Maybe (State state4), restMaybeStates ) -> ( State state4, restStates4 ) -> State tagStates1 } -> toFinalTagStates) (a8 -> Result (List Feedback) output3 -> Basics.Int -> ( ControlFns input3 state3 delta3 output3, restFns3 ) -> ( State state3, restStates3 ) -> Result (List Feedback) output3) ( Maybe a7, stateAfter ) ( stateAfter, stateAfters ) (a6 -> c2) (a5 -> c1) (a4 -> Basics.Int -> Basics.Int -> (( State argState, restArgStates ) -> tagStates) -> ( Maybe (State argState), restMaybeArgStates ) -> ( State argState, restArgStates ) -> State tagStates) (a3 -> List (Platform.Sub.Sub delta1_1) -> ( Delta delta2 -> delta1_1, restSetters1 ) -> ( ControlFns input2 state2 delta2 output2, restFns2 ) -> ( State state2, restStates2 ) -> List (Platform.Sub.Sub delta1_1)) (a2 -> c) (a1 -> { newCmds : List (Platform.Cmd.Cmd recordDelta), newStates : ( State state1, restStates1 ) -> recordState0 } -> ( ControlFns input1 state1 delta1 output1, restFns1 ) -> ( Delta delta1 -> recordDelta, restDeltaSetters ) -> ( Delta delta1, restDeltas ) -> ( State state1, restStates1 ) -> { newCmds : List (Platform.Cmd.Cmd recordDelta), newStates : recordState }) (a -> List (Subcontrol delta) -> List Alert -> ( ControlFns input state e output, restFns ) -> ( Delta e -> delta, restSetters ) -> ( State state, restStates ) -> List (Subcontrol delta))
Add a tag with two arguments to a custom type.
type Point
= Point Float Float
pointControl =
customType
(\point tag ->
case tag of
Point x y ->
point x y
)
|> tag2 "Point" Point float float
tag3 : String -> (output12 -> output11 -> output10 -> output9) -> AdvancedControl output12 state11 delta15 output12 -> AdvancedControl output11 state10 delta14 output11 -> AdvancedControl output10 state9 delta13 output10 -> CustomTypeBuilder (a21 -> destructor1 -> restInputToStateConverters -> tag -> ( State tagStates2, Platform.Cmd.Cmd delta12 )) (a20 -> List Alert -> restFns7 -> restStates8 -> List Alert) deltaAfter deltaAfters (( Delta delta14_1, a19 ) -> c7) (( ( Delta delta14_1, a19 ) -> c7, a18 ) -> c6) destructor (a17 -> List Alert -> List Feedback -> restFns6 -> restStates7 -> List Feedback) (a16 -> List Alert -> Basics.Int -> restFns5 -> restStates6 -> List Alert) (Path -> ( ControlFns ( output12, ( output11, ( output10, b ) ) ) ( State state11, ( State state10, ( State state9, End ) ) ) ( Delta delta15, ( Delta delta14, ( Delta delta13, End ) ) ) output9, a15 ) -> c5) (a14 -> Basics.Int -> restFns4 -> restStates5 -> restStates5) (Path -> ( Platform.Cmd.Cmd (Delta ( Delta delta15, ( Delta delta14, ( Delta delta13, End ) ) )), a13 ) -> c4) (Path -> ( State ( State state11, ( State state10, ( State state9, End ) ) ), a12 ) -> c3) (a11 -> List (Platform.Cmd.Cmd delta1_2) -> restDeltaSetters2 -> restDeltas1 -> List (Platform.Cmd.Cmd delta1_2)) (a10 -> befores -> afters -> next) (a9 -> { controlFns : restControlFns, deltaSetters : restDeltaSetters1, finalTagStates : nextFinalTagState -> restFinalTagStates, initialTagStates : ( State state4, restStates4 ), inputTuplizers : restInputTuplizers, maybeOverridesAfter : restMaybeOverridesAfter, maybeOverridesBefore : restMaybeOverridesBefore, tagStateOverrider : (Basics.Int -> Basics.Int -> (End -> tagStates1) -> End -> End -> State tagStates1) -> Basics.Int -> Basics.Int -> (identity -> identity) -> ( Maybe (State state4), restMaybeStates ) -> ( State state4, restStates4 ) -> State tagStates1 } -> toFinalTagStates) (a8 -> Result (List Feedback) output3 -> Basics.Int -> restFns3 -> restStates3 -> Result (List Feedback) output3) stateAfter stateAfters (( Maybe a23, a6 ) -> c2) (( ( Maybe a23, a6 ) -> c2, a5 ) -> c1) (a4 -> Basics.Int -> Basics.Int -> (restArgStates -> tagStates) -> restMaybeArgStates -> restArgStates -> State tagStates) (a3 -> List (Platform.Sub.Sub delta1_1) -> restSetters1 -> restFns2 -> restStates2 -> List (Platform.Sub.Sub delta1_1)) (( (( d, ( f, ( g, End ) ) ) -> h) -> d -> f -> g -> h, a2 ) -> c) (a1 -> { newCmds : List (Platform.Cmd.Cmd recordDelta), newStates : restStates1 -> recordState0 } -> restFns1 -> restDeltaSetters -> restDeltas -> restStates1 -> { newCmds : List (Platform.Cmd.Cmd recordDelta), newStates : recordState }) (a -> List (Subcontrol delta) -> List Alert -> restFns -> restSetters -> restStates -> List (Subcontrol delta)) -> CustomTypeBuilder (a21 -> (inputToStateConverter -> destructor1) -> ( inputToStateConverter, restInputToStateConverters ) -> tag -> ( State tagStates2, Platform.Cmd.Cmd delta12 )) (a20 -> List Alert -> ( ControlFns input8 state8 delta11 output8, restFns7 ) -> ( State state8, restStates8 ) -> List Alert) ( Delta delta10, deltaAfter ) ( deltaAfter, deltaAfters ) (a19 -> c7) (a18 -> c6) destructor (a17 -> List Alert -> List Feedback -> ( ControlFns input7 state7 delta9 output7, restFns6 ) -> ( State state7, restStates7 ) -> List Feedback) (a16 -> List Alert -> Basics.Int -> ( ControlFns input6 state6 delta8 output6, restFns5 ) -> ( State state6, restStates6 ) -> List Alert) (Path -> a15 -> c5) (a14 -> Basics.Int -> ( ControlFns input5 state5 delta7 output5, restFns4 ) -> ( State state5, restStates5 ) -> ( State state5, restStates5 )) (Path -> a13 -> c4) (Path -> a12 -> c3) (a11 -> List (Platform.Cmd.Cmd delta1_2) -> ( delta6 -> delta1_2, restDeltaSetters2 ) -> ( Platform.Cmd.Cmd delta6, restDeltas1 ) -> List (Platform.Cmd.Cmd delta1_2)) (a10 -> ( ( value, after ) -> delta5, befores ) -> ( after, afters ) -> ( value -> delta5, next )) (a9 -> { controlFns : ( ControlFns input4 state1_1 delta4 output4, restControlFns ), deltaSetters : ( Delta delta4 -> tagDelta, restDeltaSetters1 ), finalTagStates : ( finalTagState, nextFinalTagState ) -> restFinalTagStates, initialTagStates : ( State state4, restStates4 ), inputTuplizers : ( (input4 -> ( State tagStates1, Platform.Cmd.Cmd (Delta tagDelta) )) -> finalTagState, restInputTuplizers ), maybeOverridesAfter : ( maybeOverrideAfter, restMaybeOverridesAfter ), maybeOverridesBefore : ( ( Maybe (State state1_1), maybeOverrideAfter ) -> ( Maybe (State state4), restMaybeStates ), restMaybeOverridesBefore ), tagStateOverrider : (Basics.Int -> Basics.Int -> (End -> tagStates1) -> End -> End -> State tagStates1) -> Basics.Int -> Basics.Int -> (identity -> identity) -> ( Maybe (State state4), restMaybeStates ) -> ( State state4, restStates4 ) -> State tagStates1 } -> toFinalTagStates) (a8 -> Result (List Feedback) output3 -> Basics.Int -> ( ControlFns input3 state3 delta3 output3, restFns3 ) -> ( State state3, restStates3 ) -> Result (List Feedback) output3) ( Maybe a7, stateAfter ) ( stateAfter, stateAfters ) (a6 -> c2) (a5 -> c1) (a4 -> Basics.Int -> Basics.Int -> (( State argState, restArgStates ) -> tagStates) -> ( Maybe (State argState), restMaybeArgStates ) -> ( State argState, restArgStates ) -> State tagStates) (a3 -> List (Platform.Sub.Sub delta1_1) -> ( Delta delta2 -> delta1_1, restSetters1 ) -> ( ControlFns input2 state2 delta2 output2, restFns2 ) -> ( State state2, restStates2 ) -> List (Platform.Sub.Sub delta1_1)) (a2 -> c) (a1 -> { newCmds : List (Platform.Cmd.Cmd recordDelta), newStates : ( State state1, restStates1 ) -> recordState0 } -> ( ControlFns input1 state1 delta1 output1, restFns1 ) -> ( Delta delta1 -> recordDelta, restDeltaSetters ) -> ( Delta delta1, restDeltas ) -> ( State state1, restStates1 ) -> { newCmds : List (Platform.Cmd.Cmd recordDelta), newStates : recordState }) (a -> List (Subcontrol delta) -> List Alert -> ( ControlFns input state e output, restFns ) -> ( Delta e -> delta, restSetters ) -> ( State state, restStates ) -> List (Subcontrol delta))
Add a tag with three arguments to a custom type.
type Point3D
= Point3D Float Float Float
point3DControl =
customType
(\point3D tag ->
case tag of
Point3D x y z ->
point3D x y z
)
|> tag3 "Point3D" Point3D float float float
tag4 : String -> (output13 -> output12 -> output11 -> output10 -> output9) -> AdvancedControl output13 state12 delta16 output13 -> AdvancedControl output12 state11 delta15 output12 -> AdvancedControl output11 state10 delta14 output11 -> AdvancedControl output10 state9 delta13 output10 -> CustomTypeBuilder (a21 -> destructor1 -> restInputToStateConverters -> tag -> ( State tagStates2, Platform.Cmd.Cmd delta12 )) (a20 -> List Alert -> restFns7 -> restStates8 -> List Alert) deltaAfter deltaAfters (( Delta delta14_1, a19 ) -> c7) (( ( Delta delta14_1, a19 ) -> c7, a18 ) -> c6) destructor (a17 -> List Alert -> List Feedback -> restFns6 -> restStates7 -> List Feedback) (a16 -> List Alert -> Basics.Int -> restFns5 -> restStates6 -> List Alert) (Path -> ( ControlFns ( output13, ( output12, ( output11, ( output10, b ) ) ) ) ( State state12, ( State state11, ( State state10, ( State state9, End ) ) ) ) ( Delta delta16, ( Delta delta15, ( Delta delta14, ( Delta delta13, End ) ) ) ) output9, a15 ) -> c5) (a14 -> Basics.Int -> restFns4 -> restStates5 -> restStates5) (Path -> ( Platform.Cmd.Cmd (Delta ( Delta delta16, ( Delta delta15, ( Delta delta14, ( Delta delta13, End ) ) ) )), a13 ) -> c4) (Path -> ( State ( State state12, ( State state11, ( State state10, ( State state9, End ) ) ) ), a12 ) -> c3) (a11 -> List (Platform.Cmd.Cmd delta1_2) -> restDeltaSetters2 -> restDeltas1 -> List (Platform.Cmd.Cmd delta1_2)) (a10 -> befores -> afters -> next) (a9 -> { controlFns : restControlFns, deltaSetters : restDeltaSetters1, finalTagStates : nextFinalTagState -> restFinalTagStates, initialTagStates : ( State state4, restStates4 ), inputTuplizers : restInputTuplizers, maybeOverridesAfter : restMaybeOverridesAfter, maybeOverridesBefore : restMaybeOverridesBefore, tagStateOverrider : (Basics.Int -> Basics.Int -> (End -> tagStates1) -> End -> End -> State tagStates1) -> Basics.Int -> Basics.Int -> (identity -> identity) -> ( Maybe (State state4), restMaybeStates ) -> ( State state4, restStates4 ) -> State tagStates1 } -> toFinalTagStates) (a8 -> Result (List Feedback) output3 -> Basics.Int -> restFns3 -> restStates3 -> Result (List Feedback) output3) stateAfter stateAfters (( Maybe a23, a6 ) -> c2) (( ( Maybe a23, a6 ) -> c2, a5 ) -> c1) (a4 -> Basics.Int -> Basics.Int -> (restArgStates -> tagStates) -> restMaybeArgStates -> restArgStates -> State tagStates) (a3 -> List (Platform.Sub.Sub delta1_1) -> restSetters1 -> restFns2 -> restStates2 -> List (Platform.Sub.Sub delta1_1)) (( (( d, ( f, ( g, ( h, End ) ) ) ) -> i) -> d -> f -> g -> h -> i, a2 ) -> c) (a1 -> { newCmds : List (Platform.Cmd.Cmd recordDelta), newStates : restStates1 -> recordState0 } -> restFns1 -> restDeltaSetters -> restDeltas -> restStates1 -> { newCmds : List (Platform.Cmd.Cmd recordDelta), newStates : recordState }) (a -> List (Subcontrol delta) -> List Alert -> restFns -> restSetters -> restStates -> List (Subcontrol delta)) -> CustomTypeBuilder (a21 -> (inputToStateConverter -> destructor1) -> ( inputToStateConverter, restInputToStateConverters ) -> tag -> ( State tagStates2, Platform.Cmd.Cmd delta12 )) (a20 -> List Alert -> ( ControlFns input8 state8 delta11 output8, restFns7 ) -> ( State state8, restStates8 ) -> List Alert) ( Delta delta10, deltaAfter ) ( deltaAfter, deltaAfters ) (a19 -> c7) (a18 -> c6) destructor (a17 -> List Alert -> List Feedback -> ( ControlFns input7 state7 delta9 output7, restFns6 ) -> ( State state7, restStates7 ) -> List Feedback) (a16 -> List Alert -> Basics.Int -> ( ControlFns input6 state6 delta8 output6, restFns5 ) -> ( State state6, restStates6 ) -> List Alert) (Path -> a15 -> c5) (a14 -> Basics.Int -> ( ControlFns input5 state5 delta7 output5, restFns4 ) -> ( State state5, restStates5 ) -> ( State state5, restStates5 )) (Path -> a13 -> c4) (Path -> a12 -> c3) (a11 -> List (Platform.Cmd.Cmd delta1_2) -> ( delta6 -> delta1_2, restDeltaSetters2 ) -> ( Platform.Cmd.Cmd delta6, restDeltas1 ) -> List (Platform.Cmd.Cmd delta1_2)) (a10 -> ( ( value, after ) -> delta5, befores ) -> ( after, afters ) -> ( value -> delta5, next )) (a9 -> { controlFns : ( ControlFns input4 state1_1 delta4 output4, restControlFns ), deltaSetters : ( Delta delta4 -> tagDelta, restDeltaSetters1 ), finalTagStates : ( finalTagState, nextFinalTagState ) -> restFinalTagStates, initialTagStates : ( State state4, restStates4 ), inputTuplizers : ( (input4 -> ( State tagStates1, Platform.Cmd.Cmd (Delta tagDelta) )) -> finalTagState, restInputTuplizers ), maybeOverridesAfter : ( maybeOverrideAfter, restMaybeOverridesAfter ), maybeOverridesBefore : ( ( Maybe (State state1_1), maybeOverrideAfter ) -> ( Maybe (State state4), restMaybeStates ), restMaybeOverridesBefore ), tagStateOverrider : (Basics.Int -> Basics.Int -> (End -> tagStates1) -> End -> End -> State tagStates1) -> Basics.Int -> Basics.Int -> (identity -> identity) -> ( Maybe (State state4), restMaybeStates ) -> ( State state4, restStates4 ) -> State tagStates1 } -> toFinalTagStates) (a8 -> Result (List Feedback) output3 -> Basics.Int -> ( ControlFns input3 state3 delta3 output3, restFns3 ) -> ( State state3, restStates3 ) -> Result (List Feedback) output3) ( Maybe a7, stateAfter ) ( stateAfter, stateAfters ) (a6 -> c2) (a5 -> c1) (a4 -> Basics.Int -> Basics.Int -> (( State argState, restArgStates ) -> tagStates) -> ( Maybe (State argState), restMaybeArgStates ) -> ( State argState, restArgStates ) -> State tagStates) (a3 -> List (Platform.Sub.Sub delta1_1) -> ( Delta delta2 -> delta1_1, restSetters1 ) -> ( ControlFns input2 state2 delta2 output2, restFns2 ) -> ( State state2, restStates2 ) -> List (Platform.Sub.Sub delta1_1)) (a2 -> c) (a1 -> { newCmds : List (Platform.Cmd.Cmd recordDelta), newStates : ( State state1, restStates1 ) -> recordState0 } -> ( ControlFns input1 state1 delta1 output1, restFns1 ) -> ( Delta delta1 -> recordDelta, restDeltaSetters ) -> ( Delta delta1, restDeltas ) -> ( State state1, restStates1 ) -> { newCmds : List (Platform.Cmd.Cmd recordDelta), newStates : recordState }) (a -> List (Subcontrol delta) -> List Alert -> ( ControlFns input state e output, restFns ) -> ( Delta e -> delta, restSetters ) -> ( State state, restStates ) -> List (Subcontrol delta))
Add a tag with four arguments to a custom type.
tag5 : String -> (output14 -> output13 -> output12 -> output11 -> output10 -> output9) -> AdvancedControl output14 state13 delta17 output14 -> AdvancedControl output13 state12 delta16 output13 -> AdvancedControl output12 state11 delta15 output12 -> AdvancedControl output11 state10 delta14 output11 -> AdvancedControl output10 state9 delta13 output10 -> CustomTypeBuilder (a21 -> destructor1 -> restInputToStateConverters -> tag -> ( State tagStates2, Platform.Cmd.Cmd delta12 )) (a20 -> List Alert -> restFns7 -> restStates8 -> List Alert) deltaAfter deltaAfters (( Delta delta14_1, a19 ) -> c7) (( ( Delta delta14_1, a19 ) -> c7, a18 ) -> c6) destructor (a17 -> List Alert -> List Feedback -> restFns6 -> restStates7 -> List Feedback) (a16 -> List Alert -> Basics.Int -> restFns5 -> restStates6 -> List Alert) (Path -> ( ControlFns ( output14, ( output13, ( output12, ( output11, ( output10, b ) ) ) ) ) ( State state13, ( State state12, ( State state11, ( State state10, ( State state9, End ) ) ) ) ) ( Delta delta17, ( Delta delta16, ( Delta delta15, ( Delta delta14, ( Delta delta13, End ) ) ) ) ) output9, a15 ) -> c5) (a14 -> Basics.Int -> restFns4 -> restStates5 -> restStates5) (Path -> ( Platform.Cmd.Cmd (Delta ( Delta delta17, ( Delta delta16, ( Delta delta15, ( Delta delta14, ( Delta delta13, End ) ) ) ) )), a13 ) -> c4) (Path -> ( State ( State state13, ( State state12, ( State state11, ( State state10, ( State state9, End ) ) ) ) ), a12 ) -> c3) (a11 -> List (Platform.Cmd.Cmd delta1_2) -> restDeltaSetters2 -> restDeltas1 -> List (Platform.Cmd.Cmd delta1_2)) (a10 -> befores -> afters -> next) (a9 -> { controlFns : restControlFns, deltaSetters : restDeltaSetters1, finalTagStates : nextFinalTagState -> restFinalTagStates, initialTagStates : ( State state4, restStates4 ), inputTuplizers : restInputTuplizers, maybeOverridesAfter : restMaybeOverridesAfter, maybeOverridesBefore : restMaybeOverridesBefore, tagStateOverrider : (Basics.Int -> Basics.Int -> (End -> tagStates1) -> End -> End -> State tagStates1) -> Basics.Int -> Basics.Int -> (identity -> identity) -> ( Maybe (State state4), restMaybeStates ) -> ( State state4, restStates4 ) -> State tagStates1 } -> toFinalTagStates) (a8 -> Result (List Feedback) output3 -> Basics.Int -> restFns3 -> restStates3 -> Result (List Feedback) output3) stateAfter stateAfters (( Maybe a23, a6 ) -> c2) (( ( Maybe a23, a6 ) -> c2, a5 ) -> c1) (a4 -> Basics.Int -> Basics.Int -> (restArgStates -> tagStates) -> restMaybeArgStates -> restArgStates -> State tagStates) (a3 -> List (Platform.Sub.Sub delta1_1) -> restSetters1 -> restFns2 -> restStates2 -> List (Platform.Sub.Sub delta1_1)) (( (( d, ( f, ( g, ( h, ( i, End ) ) ) ) ) -> j) -> d -> f -> g -> h -> i -> j, a2 ) -> c) (a1 -> { newCmds : List (Platform.Cmd.Cmd recordDelta), newStates : restStates1 -> recordState0 } -> restFns1 -> restDeltaSetters -> restDeltas -> restStates1 -> { newCmds : List (Platform.Cmd.Cmd recordDelta), newStates : recordState }) (a -> List (Subcontrol delta) -> List Alert -> restFns -> restSetters -> restStates -> List (Subcontrol delta)) -> CustomTypeBuilder (a21 -> (inputToStateConverter -> destructor1) -> ( inputToStateConverter, restInputToStateConverters ) -> tag -> ( State tagStates2, Platform.Cmd.Cmd delta12 )) (a20 -> List Alert -> ( ControlFns input8 state8 delta11 output8, restFns7 ) -> ( State state8, restStates8 ) -> List Alert) ( Delta delta10, deltaAfter ) ( deltaAfter, deltaAfters ) (a19 -> c7) (a18 -> c6) destructor (a17 -> List Alert -> List Feedback -> ( ControlFns input7 state7 delta9 output7, restFns6 ) -> ( State state7, restStates7 ) -> List Feedback) (a16 -> List Alert -> Basics.Int -> ( ControlFns input6 state6 delta8 output6, restFns5 ) -> ( State state6, restStates6 ) -> List Alert) (Path -> a15 -> c5) (a14 -> Basics.Int -> ( ControlFns input5 state5 delta7 output5, restFns4 ) -> ( State state5, restStates5 ) -> ( State state5, restStates5 )) (Path -> a13 -> c4) (Path -> a12 -> c3) (a11 -> List (Platform.Cmd.Cmd delta1_2) -> ( delta6 -> delta1_2, restDeltaSetters2 ) -> ( Platform.Cmd.Cmd delta6, restDeltas1 ) -> List (Platform.Cmd.Cmd delta1_2)) (a10 -> ( ( value, after ) -> delta5, befores ) -> ( after, afters ) -> ( value -> delta5, next )) (a9 -> { controlFns : ( ControlFns input4 state1_1 delta4 output4, restControlFns ), deltaSetters : ( Delta delta4 -> tagDelta, restDeltaSetters1 ), finalTagStates : ( finalTagState, nextFinalTagState ) -> restFinalTagStates, initialTagStates : ( State state4, restStates4 ), inputTuplizers : ( (input4 -> ( State tagStates1, Platform.Cmd.Cmd (Delta tagDelta) )) -> finalTagState, restInputTuplizers ), maybeOverridesAfter : ( maybeOverrideAfter, restMaybeOverridesAfter ), maybeOverridesBefore : ( ( Maybe (State state1_1), maybeOverrideAfter ) -> ( Maybe (State state4), restMaybeStates ), restMaybeOverridesBefore ), tagStateOverrider : (Basics.Int -> Basics.Int -> (End -> tagStates1) -> End -> End -> State tagStates1) -> Basics.Int -> Basics.Int -> (identity -> identity) -> ( Maybe (State state4), restMaybeStates ) -> ( State state4, restStates4 ) -> State tagStates1 } -> toFinalTagStates) (a8 -> Result (List Feedback) output3 -> Basics.Int -> ( ControlFns input3 state3 delta3 output3, restFns3 ) -> ( State state3, restStates3 ) -> Result (List Feedback) output3) ( Maybe a7, stateAfter ) ( stateAfter, stateAfters ) (a6 -> c2) (a5 -> c1) (a4 -> Basics.Int -> Basics.Int -> (( State argState, restArgStates ) -> tagStates) -> ( Maybe (State argState), restMaybeArgStates ) -> ( State argState, restArgStates ) -> State tagStates) (a3 -> List (Platform.Sub.Sub delta1_1) -> ( Delta delta2 -> delta1_1, restSetters1 ) -> ( ControlFns input2 state2 delta2 output2, restFns2 ) -> ( State state2, restStates2 ) -> List (Platform.Sub.Sub delta1_1)) (a2 -> c) (a1 -> { newCmds : List (Platform.Cmd.Cmd recordDelta), newStates : ( State state1, restStates1 ) -> recordState0 } -> ( ControlFns input1 state1 delta1 output1, restFns1 ) -> ( Delta delta1 -> recordDelta, restDeltaSetters ) -> ( Delta delta1, restDeltas ) -> ( State state1, restStates1 ) -> { newCmds : List (Platform.Cmd.Cmd recordDelta), newStates : recordState }) (a -> List (Subcontrol delta) -> List Alert -> ( ControlFns input state e output, restFns ) -> ( Delta e -> delta, restSetters ) -> ( State state, restStates ) -> List (Subcontrol delta))
Add a tag with five arguments to a custom type.
endCustomType : CustomTypeBuilder (((input -> ( State ( State state, restStates ), Platform.Cmd.Cmd (Delta ( Delta delta, restDeltas )) )) -> End -> input -> ( State ( State state, restStates ), Platform.Cmd.Cmd (Delta ( Delta delta, restDeltas )) )) -> (inputToStateConverter -> destructor) -> ( inputToStateConverter, restInputToStateConverters ) -> input -> ( State ( State state, restStates ), Platform.Cmd.Cmd (Delta ( Delta delta, restDeltas )) )) ((List Alert -> End -> End -> List Alert) -> List Alert -> ( ControlFns input1 state delta output1, restFns ) -> ( State state, restStates ) -> List Alert) deltaAfter afters deltaBefore (End -> befores) (inputToStateConverter -> destructor) ((List Alert -> List Feedback -> End -> End -> List Feedback) -> List Alert -> List Feedback -> ( ControlFns input1 state delta output1, restFns ) -> ( State state, restStates ) -> List Feedback) ((List Alert -> Basics.Int -> End -> End -> List Alert) -> List Alert -> Basics.Int -> ( ControlFns input1 state delta output1, restFns ) -> ( State state, restStates ) -> List Alert) (Path -> End -> ( ControlFns input1 state delta output1, restFns )) ((Basics.Int -> End -> End -> End) -> Basics.Int -> ( ControlFns input1 state delta output1, restFns ) -> ( State state, restStates ) -> ( State state, restStates )) (Path -> End -> deltas) (Path -> End -> ( State state, restStates )) ((List (Platform.Cmd.Cmd ( Delta delta, restDeltas )) -> End -> End -> List (Platform.Cmd.Cmd ( Delta delta, restDeltas ))) -> List (Platform.Cmd.Cmd ( Delta delta, restDeltas )) -> ( setter, restSetters ) -> deltas -> List (Platform.Cmd.Cmd ( Delta delta, restDeltas ))) ((End -> End -> End) -> befores -> afters -> ( setter, restSetters )) (({ c | finalTagStates : End -> b2 } -> b2) -> { controlFns : ( ControlFns input1 state delta output1, restFns ), deltaSetters : ( setter, restSetters ), finalTagStates : a1 -> a1, initialTagStates : ( State state, restStates ), inputTuplizers : g, maybeOverridesAfter : h, maybeOverridesBefore : i, tagStateOverrider : j } -> ( inputToStateConverter, restInputToStateConverters )) ((a -> b1 -> End -> End -> a) -> Result (List Feedback) value -> Basics.Int -> ( ControlFns input1 state delta output1, restFns ) -> ( State state, restStates ) -> Result (List Feedback) output) stateAfter h stateBefore (End -> i) j ((List (Platform.Sub.Sub ( Delta delta, restDeltas )) -> End -> End -> End -> List (Platform.Sub.Sub ( Delta delta, restDeltas ))) -> List (Platform.Sub.Sub ( Delta delta, restDeltas )) -> ( setter, restSetters ) -> ( ControlFns input1 state delta output1, restFns ) -> ( State state, restStates ) -> List (Platform.Sub.Sub ( Delta delta, restDeltas ))) (End -> g) (({ newCmds : List (Platform.Cmd.Cmd ( Delta delta, restDeltas )), newStates : End -> ( State state, restStates ) } -> End -> End -> End -> End -> { newCmds : List (Platform.Cmd.Cmd ( Delta delta, restDeltas )), newStates : End -> ( State state, restStates ) }) -> { newCmds : List (Platform.Cmd.Cmd ( Delta delta, restDeltas )), newStates : ( State state, restStates ) -> ( State state, restStates ) } -> ( ControlFns input1 state delta output1, restFns ) -> ( setter, restSetters ) -> ( Delta delta, restDeltas ) -> ( State state, restStates ) -> { newCmds : List (Platform.Cmd.Cmd ( Delta delta, restDeltas )), newStates : End -> ( State state, restStates ) }) ((List (Subcontrol ( Delta delta, restDeltas )) -> b -> End -> End -> End -> List (Subcontrol ( Delta delta, restDeltas ))) -> List (Subcontrol ( Delta delta, restDeltas )) -> List Alert -> ( ControlFns input1 state delta output1, restFns ) -> ( setter, restSetters ) -> ( State state, restStates ) -> List (Subcontrol ( Delta delta, restDeltas ))) -> AdvancedControl input ( State state, restStates ) ( Delta delta, restDeltas ) output
Finalise the construction of a customType
combinator.
type alias Foo
= Bar
| Baz
helloControl =
customType
(\bar baz tag ->
case tag ofcustomType
Bar -> bar
Baz -> baz
)
|> tag0 "Bar" Bar
|> tag0 "Baz" Baz
|> endCustomType
These are types that you will see in your form's State
and Delta
type signatures.
State
is the form's equivalent of an Elm program's Model
type. It is
used to manage the form's internal state.
A Delta
is the form's equivalent of an Elm program's Msg
type. It is
used internally within a form to update its state.
Special Delta
type used only by list
controls
Under the hood, this library encodes complex Elm types (such as records and
custom types) as nested tuples, which are used in both the State
and Delta
types for each Control
. The End
type is used to mark the end of a nested
tuple.
For example, the State
for this Elm type:
type alias User =
{ name : String, age : Int }
Could be encoded as:
( String, ( Int, End ) )
A user of this package shouldn't need to know about any of these types - they are only exposed to make it possible to write type signatures.
A slightly more flexible version of Control
Some internal stuff needed to build up record and custom type controls
Some internal stuff needed to handle validations
Some internal stuff needed to build up a record control
an internal type needed to represent the validation state of a control
{ state : state
, status : Status
, alerts : List Alert
, selected : Basics.Int
, name : String
, id : String
, label : String
, class : List String
}
Some internal stuff needed to view controls
Path
an internal type needed to track the position of a control within a tree of controls
{ path : Path
, label : String
, message : String
, fail : Basics.Bool
}
Some internal stuff to handle validation