edkelly303/elm-any-type-forms/2.0.0

NOTE: the latest version is 8.1.0

Control

Creating a form

type alias Control state delta output =
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.

type alias Form state delta output msg =
{ init : ( State state, Cmd msg )
, initWith : output -> ( State state, Cmd msg )
, update : Delta delta -> State state -> ( State state, Cmd msg )
, view : State state -> Html msg
, subscriptions : State state -> Sub msg
, submit :
State state
-> ( State state, Result (List ( String, String )) output )
}

A Form is an interface containing functions that you can use in your program to initialise, view, update, subscribe, and submit your form.

{ outputToString : output -> String
, title : String
, control : Control state delta output
}
-> 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 Modeland 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 Modeland Msg types wherever appropriate.

main : Program () (State String) (Delta String)
main =
    sandbox
        { control = int
        , title = "Just a simple Int control"
        , outputToString = Debug.toString
        }
{ control : Control state delta output
, title : String
, onUpdate : Delta delta -> msg
, onSubmit : msg
}
-> Form state delta output msg

Convert a Control into a Form, which you can then plumb into your Elm application. 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.

type alias Msg
    = FormUpdated (Delta String)
    | FormSubmitted


myForm : Form (State String) (Delta String) Int Msg
myForm =
    form
        { control = int
        , title = "Just a simple Int control"
        , onUpdate = FormUpdated
        , onSubmit = FormSubmitted
        }

Basic controls

bool : Control Bool Bool Bool

A control that produces a Bool. Renders as an HTML checkbox.

int : Control String String Int

A control that produces an Int. Renders as an HTML number input.

float : Control String String 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.

( 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 ) ]

Basic combinators

{ wrap : output -> wrapped
, unwrap : wrapped -> output
}
-> Control state delta output
-> Control ( State state, End ) ( Delta delta, End ) wrapped

A combinator that produces a wrapper type around a given type.

type Id
    = Id Int


idControl =
    wrapper { wrap = Id, unwrap = \(Id i) -> i } int
( String, Control state1 delta1 output1 )
-> ( String, 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 ( "First", string ) ( "Second", int )
( String, Control state1 delta1 output1 )
-> ( String, Control state2 delta2 output2 )
-> ( String, 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 ( "First", string ) ( "Second", int ) ( "Third", float )
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
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
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
( String, Control keyState keyDelta comparable )
-> ( String, Control valueState valueDelta value )
-> Control
(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 ( "Key", int ) ( "Value", 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
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

Creating a new control

type alias ControlConfig state delta output =
{ initEmpty : ( state, Cmd delta )
, initWith : output -> ( state, Cmd delta )
, update : delta -> state -> ( state, Cmd delta )
, view :
{ label : String
, id : String
, name : String
, class : String
, state : state
}
-> Html delta
, subscriptions : state -> Sub delta
, parse : state -> Result (List String) output
}

Configuration for a custom control. You need to supply the following fields:

  • initEmpty: a default initial "empty" value for the state of the control. For a control whose state is of type String, this might be "", for a number it might be 0.
  • initWith: a function that initialises the control's state from a value of the control's output type. For a control that outputs an Int, but whose state is a String, this might be String.fromInt.
  • 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
        { initEmpty = 0
        , initWith = 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
        }

Validating controls

Simple validation

(output -> Bool)
-> String
-> Control state delta output
-> Control state delta output

Display an error on a Control if its output fails to meet the predicate.

positiveInt =
    int
        |> failIf
            (\x -> x < 1)
            "Must be greater than zero!"

Multi-field validation

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 helpful error messages on both fields if they don't. You can achieve this as follows:

passwordControl =
    record
        (\password confirmation ->
            { password = password
            , confirmation = confirmation
            }
        )
        |> field "Enter password"
            (string
                |> catchFlag
                    "flag-passwords-do-not-match"
                    "Must match 'Confirm password' field"
            )
        |> field "Confirm password"
            (string
                |> catchFlag
                    "flag-passwords-do-not-match"
                    "Must match 'Enter password' field"
            )
        |> end
        |> throwFlagIf
            (\{ password, confirmation } -> password /= confirmation)
            "flag-passwords-do-not-match"
(output -> Bool)
-> String
-> Control state delta output
-> Control state delta output

Throw a "flag" from a Control if its output fails to meet the predicate.

This is meant to be used in combination with catchFlag, which catches the "flag" and displays an error.

String
-> String
-> Control state delta output
-> Control state delta output

Catch a "flag" thrown by another Control and display an error on this control.

This is meant to be used in combination with throwFlagIf, which throws the "flag".

List validation

(output -> List 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
        |> catchFlag
            "flag-hello-world"
            "The first two items in the list must not be \"hello\" and \"world\".")


list myString
    |> throwFlagsAt
        (\list_ ->
            case list of
                "hello" :: "world" :: _ -> [ 0, 1 ]


                _ -> []
        )
        "flag-hello-world"

Configuring controls

input
-> AdvancedControl input state delta output
-> AdvancedControl input state delta output

Initialise a Control using a value of the type that the Control outputs.

oneAndHello =
    tuple ( "Int", int ) ( "String", string )
        |> initWith ( 1, "hello" )
debounce : 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 -> Control state delta output -> Control 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"
List ( String, 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 )
            ]

Building record combinators

b
{ after : End
, afters : End
, before : a12 -> a12
, befores : a11 -> a11
, debouncingReceiverCollector : a10 -> a10
, deltaInitialiser : a9 -> a9
, errorCollector : a8 -> a8
, flagEmitter : a7 -> a7
, fns : d -> e -> e
, idleSetter : a6 -> a6
, index : number
, initialDeltas : f -> g -> g
, initialStates : h -> i -> i
, initialiser : a5 -> a5
, labels : List j
, makeSetters : a4 -> a4
, parser : a3 -> a3
, subscriptionCollector : a2 -> a2
, toOutput : b
, updater : a1 -> a1
, viewer : a -> a
}
c

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 "Name" string
        |> field "Age" int
        |> end
String
-> b
-> AdvancedControl input7 state8 delta10 output8
{ n
| after : d
, afters : e
, before : ( Delta delta11, a17 ) -> c5
, befores : ( ( Delta delta11, a17 ) -> c5, a16 ) -> c4
, debouncingReceiverCollector :
a15 -> List Flag -> restFns7 -> restStates7 -> List Flag
, deltaInitialiser : a14 -> List (Cmd msg1) -> f -> g -> h
, errorCollector :
a12
-> List Flag
-> List ( String, String )
-> restFns6
-> restStates6
-> List ( String, String )
, flagEmitter : a11 -> List Flag -> restFns5 -> restStates5 -> List Flag
, fns :
Path
-> ( { access : Access
, field : ControlFns input7 state8 delta10 output8
, fromInput : b
}
, a10
)
-> c3
, idleSetter : a9 -> restFns4 -> restStates4 -> restStates4
, index : number
, initialDeltas : Path -> ( Cmd (Delta delta10), a8 ) -> c2
, initialStates : Path -> ( State state8, a7 ) -> c1
, initialiser : a6 -> recordInput -> restFns3 -> restStates3
, labels : List String
, makeSetters : a5 -> befores -> afters -> next
, parser :
a4
-> Result (List ( String, String )) output1_1
-> restFns2
-> restStates2
-> Result (List ( String, String )) output2
, subscriptionCollector : a3 -> List (Sub msg) -> i -> j -> k -> l
, toOutput : m
, updater :
a1
-> { newCmds : List (Cmd recordDelta1)
, newStates : restStates1 -> recordState0
}
-> restFns1
-> restDeltaSetters1
-> restDeltas
-> restStates1
-> { newCmds : List (Cmd recordDelta1)
, newStates : recordState1
}
, viewer :
a
-> List (Html (Delta recordDelta))
-> List Flag
-> restFns
-> restDeltaSetters
-> restStates
-> List (Html (Delta recordDelta))
}
c
{ after : ( Delta delta9, d )
, afters : ( d, e )
, before : a17 -> c5
, befores : a16 -> c4
, debouncingReceiverCollector :
a15
-> List Flag
-> ( RecordFns input6 state7 delta8 output7 recordOutput6
, restFns7
)
-> ( State state7, restStates7 )
-> List Flag
, deltaInitialiser :
a14 -> List (Cmd msg1) -> ( a13 -> msg1, f ) -> ( Cmd a13, g ) -> h
, errorCollector :
a12
-> List Flag
-> List ( String, String )
-> ( RecordFns input5 state6 delta7 output6 recordOutput5
, restFns6
)
-> ( State state6, restStates6 )
-> List ( String, String )
, flagEmitter :
a11
-> List Flag
-> ( RecordFns input4 state5 delta6 output5 recordOutput4
, restFns5
)
-> ( State state5, restStates5 )
-> List Flag
, fns : Path -> a10 -> c3
, idleSetter :
a9
-> ( RecordFns input3 state4 delta5 output4 recordOutput3
, restFns4
)
-> ( State state4, restStates4 )
-> ( State state4, restStates4 )
, index : number
, initialDeltas : Path -> a8 -> c2
, initialStates : Path -> a7 -> c1
, initialiser :
a6
-> recordInput
-> ( RecordFns output3 state3 delta4 output3 recordInput
, restFns3
)
-> ( State state3, restStates3 )
, labels : List String
, makeSetters :
a5
-> ( ( value, after ) -> delta3, befores )
-> ( after, afters )
-> ( value -> delta3, next )
, parser :
a4
-> Result (List ( String, String )) (output0 -> output1_1)
-> ( RecordFns input2 state2 delta2 output0 recordOutput2
, restFns2
)
-> ( State state2, restStates2 )
-> Result (List ( String, String )) output2
, subscriptionCollector :
a3
-> List (Sub msg)
-> ( a2 -> msg, i )
-> ( { q | field : { p | subscriptions : o -> Sub a2 } }, j )
-> ( o, k )
-> l
, toOutput : m
, updater :
a1
-> { newCmds : List (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 (Cmd recordDelta1)
, newStates : recordState1
}
, viewer :
a
-> List (Html (Delta recordDelta))
-> List Flag
-> ( RecordFns input state delta output recordOutput, restFns )
-> ( Delta delta -> recordDelta, restDeltaSetters )
-> ( State state, restStates )
-> List (Html (Delta recordDelta))
}
c

Add a field to a record combinator.

type alias Hello =
    { hello : String }


helloControl =
    record Hello
        |> field "Hello" string
        |> end
String
-> b
-> AdvancedControl input7 state8 delta10 output8
{ n
| after : d
, afters : e
, before : ( Delta delta11, a17 ) -> c5
, befores : ( ( Delta delta11, a17 ) -> c5, a16 ) -> c4
, debouncingReceiverCollector :
a15 -> List Flag -> restFns7 -> restStates7 -> List Flag
, deltaInitialiser : a14 -> List (Cmd msg1) -> f -> g -> h
, errorCollector :
a12
-> List Flag
-> List ( String, String )
-> restFns6
-> restStates6
-> List ( String, String )
, flagEmitter : a11 -> List Flag -> restFns5 -> restStates5 -> List Flag
, fns :
Path
-> ( { access : Access
, field : ControlFns input7 state8 delta10 output8
, fromInput : b
}
, a10
)
-> c3
, idleSetter : a9 -> restFns4 -> restStates4 -> restStates4
, index : number
, initialDeltas : Path -> ( Cmd (Delta delta10), a8 ) -> c2
, initialStates : Path -> ( State state8, a7 ) -> c1
, initialiser : a6 -> recordInput -> restFns3 -> restStates3
, labels : List String
, makeSetters : a5 -> befores -> afters -> next
, parser :
a4
-> Result (List ( String, String )) output1_1
-> restFns2
-> restStates2
-> Result (List ( String, String )) output2
, subscriptionCollector : a3 -> List (Sub msg) -> i -> j -> k -> l
, toOutput : m
, updater :
a1
-> { newCmds : List (Cmd recordDelta1)
, newStates : restStates1 -> recordState0
}
-> restFns1
-> restDeltaSetters1
-> restDeltas
-> restStates1
-> { newCmds : List (Cmd recordDelta1)
, newStates : recordState1
}
, viewer :
a
-> List (Html (Delta recordDelta))
-> List Flag
-> restFns
-> restDeltaSetters
-> restStates
-> List (Html (Delta recordDelta))
}
c
{ after : ( Delta delta9, d )
, afters : ( d, e )
, before : a17 -> c5
, befores : a16 -> c4
, debouncingReceiverCollector :
a15
-> List Flag
-> ( RecordFns input6 state7 delta8 output7 recordOutput6
, restFns7
)
-> ( State state7, restStates7 )
-> List Flag
, deltaInitialiser :
a14 -> List (Cmd msg1) -> ( a13 -> msg1, f ) -> ( Cmd a13, g ) -> h
, errorCollector :
a12
-> List Flag
-> List ( String, String )
-> ( RecordFns input5 state6 delta7 output6 recordOutput5
, restFns6
)
-> ( State state6, restStates6 )
-> List ( String, String )
, flagEmitter :
a11
-> List Flag
-> ( RecordFns input4 state5 delta6 output5 recordOutput4
, restFns5
)
-> ( State state5, restStates5 )
-> List Flag
, fns : Path -> a10 -> c3
, idleSetter :
a9
-> ( RecordFns input3 state4 delta5 output4 recordOutput3
, restFns4
)
-> ( State state4, restStates4 )
-> ( State state4, restStates4 )
, index : number
, initialDeltas : Path -> a8 -> c2
, initialStates : Path -> a7 -> c1
, initialiser :
a6
-> recordInput
-> ( RecordFns output3 state3 delta4 output3 recordInput
, restFns3
)
-> ( State state3, restStates3 )
, labels : List String
, makeSetters :
a5
-> ( ( value, after ) -> delta3, befores )
-> ( after, afters )
-> ( value -> delta3, next )
, parser :
a4
-> Result (List ( String, String )) (output0 -> output1_1)
-> ( RecordFns input2 state2 delta2 output0 recordOutput2
, restFns2
)
-> ( State state2, restStates2 )
-> Result (List ( String, String )) output2
, subscriptionCollector :
a3
-> List (Sub msg)
-> ( a2 -> msg, i )
-> ( { q | field : { p | subscriptions : o -> Sub a2 } }, j )
-> ( o, k )
-> l
, toOutput : m
, updater :
a1
-> { newCmds : List (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 (Cmd recordDelta1)
, newStates : recordState1
}
, viewer :
a
-> List (Html (Delta recordDelta))
-> List Flag
-> ( RecordFns input state delta output recordOutput, restFns )
-> ( Delta delta -> recordDelta, restDeltaSetters )
-> ( State state, restStates )
-> List (Html (Delta recordDelta))
}
c

Add a hidden field to a record combinator.

type alias Hello =
    { hello : String }


helloControl =
    record Hello
        |> hiddenField "Hello" string
        |> end
String
-> b
-> AdvancedControl input7 state8 delta10 output8
{ n
| after : d
, afters : e
, before : ( Delta delta11, a17 ) -> c5
, befores : ( ( Delta delta11, a17 ) -> c5, a16 ) -> c4
, debouncingReceiverCollector :
a15 -> List Flag -> restFns7 -> restStates7 -> List Flag
, deltaInitialiser : a14 -> List (Cmd msg1) -> f -> g -> h
, errorCollector :
a12
-> List Flag
-> List ( String, String )
-> restFns6
-> restStates6
-> List ( String, String )
, flagEmitter : a11 -> List Flag -> restFns5 -> restStates5 -> List Flag
, fns :
Path
-> ( { access : Access
, field : ControlFns input7 state8 delta10 output8
, fromInput : b
}
, a10
)
-> c3
, idleSetter : a9 -> restFns4 -> restStates4 -> restStates4
, index : number
, initialDeltas : Path -> ( Cmd (Delta delta10), a8 ) -> c2
, initialStates : Path -> ( State state8, a7 ) -> c1
, initialiser : a6 -> recordInput -> restFns3 -> restStates3
, labels : List String
, makeSetters : a5 -> befores -> afters -> next
, parser :
a4
-> Result (List ( String, String )) output1_1
-> restFns2
-> restStates2
-> Result (List ( String, String )) output2
, subscriptionCollector : a3 -> List (Sub msg) -> i -> j -> k -> l
, toOutput : m
, updater :
a1
-> { newCmds : List (Cmd recordDelta1)
, newStates : restStates1 -> recordState0
}
-> restFns1
-> restDeltaSetters1
-> restDeltas
-> restStates1
-> { newCmds : List (Cmd recordDelta1)
, newStates : recordState1
}
, viewer :
a
-> List (Html (Delta recordDelta))
-> List Flag
-> restFns
-> restDeltaSetters
-> restStates
-> List (Html (Delta recordDelta))
}
c
{ after : ( Delta delta9, d )
, afters : ( d, e )
, before : a17 -> c5
, befores : a16 -> c4
, debouncingReceiverCollector :
a15
-> List Flag
-> ( RecordFns input6 state7 delta8 output7 recordOutput6
, restFns7
)
-> ( State state7, restStates7 )
-> List Flag
, deltaInitialiser :
a14 -> List (Cmd msg1) -> ( a13 -> msg1, f ) -> ( Cmd a13, g ) -> h
, errorCollector :
a12
-> List Flag
-> List ( String, String )
-> ( RecordFns input5 state6 delta7 output6 recordOutput5
, restFns6
)
-> ( State state6, restStates6 )
-> List ( String, String )
, flagEmitter :
a11
-> List Flag
-> ( RecordFns input4 state5 delta6 output5 recordOutput4
, restFns5
)
-> ( State state5, restStates5 )
-> List Flag
, fns : Path -> a10 -> c3
, idleSetter :
a9
-> ( RecordFns input3 state4 delta5 output4 recordOutput3
, restFns4
)
-> ( State state4, restStates4 )
-> ( State state4, restStates4 )
, index : number
, initialDeltas : Path -> a8 -> c2
, initialStates : Path -> a7 -> c1
, initialiser :
a6
-> recordInput
-> ( RecordFns output3 state3 delta4 output3 recordInput
, restFns3
)
-> ( State state3, restStates3 )
, labels : List String
, makeSetters :
a5
-> ( ( value, after ) -> delta3, befores )
-> ( after, afters )
-> ( value -> delta3, next )
, parser :
a4
-> Result (List ( String, String )) (output0 -> output1_1)
-> ( RecordFns input2 state2 delta2 output0 recordOutput2
, restFns2
)
-> ( State state2, restStates2 )
-> Result (List ( String, String )) output2
, subscriptionCollector :
a3
-> List (Sub msg)
-> ( a2 -> msg, i )
-> ( { q | field : { p | subscriptions : o -> Sub a2 } }, j )
-> ( o, k )
-> l
, toOutput : m
, updater :
a1
-> { newCmds : List (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 (Cmd recordDelta1)
, newStates : recordState1
}
, viewer :
a
-> List (Html (Delta recordDelta))
-> List Flag
-> ( RecordFns input state delta output recordOutput, restFns )
-> ( Delta delta -> recordDelta, restDeltaSetters )
-> ( State state, restStates )
-> List (Html (Delta recordDelta))
}
c

Add a read-only field to a record combinator.

type alias Hello =
    { hello : String }


helloControl =
    record Hello
        |> readOnlyfield "Hello" string
        |> end
end :
{ l
| afters : afters1
, befores : End -> befores1
, debouncingReceiverCollector :
(List Flag -> End -> End -> List Flag)
-> List Flag
-> ( RecordFns input2 state delta output2 recordOutput, restFns1 )
-> ( State state, restStates )
-> List Flag
, deltaInitialiser :
(d -> End -> End -> d)
-> List e
-> ( Delta delta -> recordDelta, restDeltaSetters )
-> i
-> List (Cmd ( Delta delta, restDeltas ))
, errorCollector :
( List Flag
-> List ( String, String )
-> End
-> End
-> List ( String, String )
)
-> List Flag
-> List ( String, String )
-> ( RecordFns input2 state delta output2 recordOutput, restFns1 )
-> ( State state, restStates )
-> List ( String, String )
, flagEmitter :
(List Flag -> End -> End -> List Flag)
-> List Flag
-> ( RecordFns input2 state delta output2 recordOutput, restFns1 )
-> ( State state, restStates )
-> List Flag
, fns :
Path
-> End
-> ( RecordFns input2 state delta output2 recordOutput, restFns1 )
, idleSetter :
(End -> End -> End)
-> ( RecordFns input2 state delta output2 recordOutput, restFns1 )
-> ( State state, restStates )
-> ( State state, restStates )
, initialDeltas : Path -> End -> i
, initialStates : Path -> End -> ( State state, restStates )
, initialiser :
(input -> End -> End)
-> input
-> ( RecordFns input2 state delta output2 recordOutput, restFns1 )
-> ( State state, restStates )
, makeSetters :
(End -> End -> End)
-> befores1
-> afters1
-> ( Delta delta -> recordDelta, restDeltaSetters )
, parser :
( Result (List ( String, String )) output
-> End
-> End
-> Result (List ( String, String )) output
)
-> Result (List ( String, String )) output1_1
-> ( RecordFns input2 state delta output2 recordOutput, restFns1 )
-> ( State state, restStates )
-> Result (List ( String, String )) output
, subscriptionCollector :
(j -> End -> End -> End -> j)
-> List k
-> ( Delta delta -> recordDelta, restDeltaSetters )
-> ( RecordFns input2 state delta output2 recordOutput, restFns1 )
-> ( State state, restStates )
-> List (Sub ( Delta delta, restDeltas ))
, toOutput : output1_1
, updater :
( { newCmds : List (Cmd ( Delta delta, restDeltas ))
, newStates : End -> ( State state, restStates )
}
-> End
-> End
-> End
-> End
-> { newCmds : List (Cmd ( Delta delta, restDeltas ))
, newStates : End -> ( State state, restStates )
}
)
-> { newCmds : List (Cmd ( Delta delta, restDeltas ))
, newStates :
( State state, restStates ) -> ( State state, restStates )
}
-> ( RecordFns input2 state delta output2 recordOutput, restFns1 )
-> ( Delta delta -> recordDelta, restDeltaSetters )
-> ( Delta delta, restDeltas )
-> ( State state, restStates )
-> { newCmds : List (Cmd ( Delta delta, restDeltas ))
, newStates : End -> ( State state, restStates )
}
, viewer :
( List (Html (Delta ( Delta delta, restDeltas )))
-> List Flag
-> End
-> End
-> End
-> List (Html (Delta ( Delta delta, restDeltas )))
)
-> List (Html (Delta ( Delta delta, restDeltas )))
-> List Flag
-> ( RecordFns input2 state delta output2 recordOutput, restFns1 )
-> ( Delta delta -> recordDelta, restDeltaSetters )
-> ( State state, restStates )
-> List (Html (Delta ( Delta delta, restDeltas )))
}
{ r
| applyInputs :
(state1 -> End -> state1)
-> (stateSetter -> state0)
-> ( stateSetter, restStateSetters )
-> input
-> State ( State state, restStates )
, debouncingReceiverCollector :
(List Flag -> End -> End -> List Flag)
-> List Flag
-> ( ControlFns input1 state delta output1, restFns )
-> ( State state, restStates )
-> List Flag
, deltaAfters : afters
, deltaBefores : End -> befores
, destructor : stateSetter -> state0
, errorCollector :
( List Flag
-> List ( String, String )
-> End
-> End
-> List ( String, String )
)
-> List Flag
-> List ( String, String )
-> ( ControlFns input1 state delta output1, restFns )
-> ( State state, restStates )
-> List ( String, String )
, flagEmitter :
(List Flag -> Int -> End -> End -> List Flag)
-> List Flag
-> Int
-> ( ControlFns input1 state delta output1, restFns )
-> ( State state, restStates )
-> List Flag
, fns :
Path -> End -> ( ControlFns input1 state delta output1, restFns )
, idleSetter :
(Int -> End -> End -> End)
-> Int
-> ( ControlFns input1 state delta output1, restFns )
-> ( State state, restStates )
-> ( State state, restStates )
, initialDeltas : Path -> End -> m
, initialStates : Path -> End -> ( State state, restStates )
, initialiseDeltas :
(n -> End -> End -> n)
-> List o
-> ( Delta delta -> ( Delta delta, restDeltas ), restSetters )
-> m
-> List (Cmd ( Delta delta, restDeltas ))
, labels : List String
, makeDeltaSetters :
(End -> End -> End)
-> befores
-> afters
-> ( Delta delta -> ( Delta delta, restDeltas ), restSetters )
, makeStateSetters :
(a1 -> b1 -> End -> End -> End -> End -> End)
-> c
-> ( State state, restStates )
-> ( ControlFns input1 state delta output1, restFns )
-> f
-> g
-> h
-> ( stateSetter, restStateSetters )
, parser :
(a -> b -> End -> End -> a)
-> Result (List ( String, String )) value
-> Int
-> ( ControlFns input1 state delta output1, restFns )
-> ( State state, restStates )
-> Result (List ( String, String )) output
, stateAfters : h
, stateBefores : End -> g
, stateInserter : c
, subscriptionCollector :
(p -> End -> End -> End -> p)
-> List q
-> ( Delta delta -> ( Delta delta, restDeltas ), restSetters )
-> ( ControlFns input1 state delta output1, restFns )
-> ( State state, restStates )
-> List (Sub ( Delta delta, restDeltas ))
, toArgStates : End -> f
, updater :
( { newCmds : List (Cmd ( Delta delta, restDeltas ))
, newStates : End -> ( State state, restStates )
}
-> End
-> End
-> End
-> End
-> { newCmds : List (Cmd ( Delta delta, restDeltas ))
, newStates : End -> ( State state, restStates )
}
)
-> { newCmds : List (Cmd ( Delta delta, restDeltas ))
, newStates :
( State state, restStates ) -> ( State state, restStates )
}
-> ( ControlFns input1 state delta output1, restFns )
-> ( Delta delta -> ( Delta delta, restDeltas ), restSetters )
-> ( Delta delta, restDeltas )
-> ( State state, restStates )
-> { newCmds : List (Cmd ( Delta delta, restDeltas ))
, newStates : End -> ( State state, restStates )
}
, viewer :
( Maybe (Html ( Delta delta, restDeltas ))
-> List Flag
-> Int
-> End
-> End
-> End
-> Maybe (Html ( Delta delta, restDeltas ))
)
-> Maybe (Html ( Delta delta, restDeltas ))
-> List Flag
-> Int
-> ( ControlFns input1 state delta output1, restFns )
-> ( Delta delta -> ( Delta delta, restDeltas ), restSetters )
-> ( State state, restStates )
-> Maybe (Html ( Delta delta, restDeltas ))
}
input
( State state, restStates )
( Delta delta, restDeltas )
output

Finalise the construction of a record or customType combinator.

type alias Hello =
    { hello : String }


helloControl =
    record Hello
        |> field "Hello" string
        |> end
( List (Html (Delta delta))
-> ViewConfigStatic
-> ViewConfigDynamic state
-> Html (Delta delta)
)
-> Control state delta output
-> Control state delta output

Change the layout of the fields of a record control.

type alias MyRecord =
    { name : String
    , age : Int
    }


myRecordControl =
    record
        (\name age ->
            { name = name
            , age = age
            }
        )
        |> field "Name" string
        |> field "Age" int
        |> end
        |> layout (\fieldViews staticConfig dynamicConfig -> Html.div [] fieldViews)

Building custom type combinators

b
r
{ applyInputs : a17 -> a17
, debouncingReceiverCollector : a16 -> a16
, deltaAfter : End
, deltaAfters : End
, deltaBefore : a15 -> a15
, deltaBefores : a14 -> a14
, destructor : b
, errorCollector : a13 -> a13
, flagEmitter : a12 -> a12
, fns : c -> d -> d
, idleSetter : a11 -> a11
, index : number
, initialDeltas : e -> f -> f
, initialStates : g -> h -> h
, initialiseDeltas : a10 -> a10
, labels : List i
, makeDeltaSetters : a9 -> a9
, makeStateSetters : a8 -> a8
, parser : a7 -> a7
, stateAfter : End
, stateAfters : End
, stateBefore : a6 -> a6
, stateBefores : a5 -> a5
, stateInserter : a4 -> a4
, subscriptionCollector : a3 -> a3
, toArgStates : a2 -> a2
, updater : a1 -> a1
, viewer : a -> a
}

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", int ) ( "Float", float )
        |> end
String
-> output8
r
{ p
| applyInputs : a23 -> state0 -> restStateSetters1 -> state1_1
, debouncingReceiverCollector :
a22 -> List Flag -> restFns7 -> restStates6 -> List Flag
, deltaAfter : b
, deltaAfters : d
, deltaBefore : ( Delta delta10, a21 ) -> c8
, deltaBefores : ( ( Delta delta10, a21 ) -> c8, a20 ) -> c7
, destructor : e
, errorCollector :
a19
-> List Flag
-> List ( String, String )
-> restFns6
-> restStates5
-> List ( String, String )
, flagEmitter :
a18 -> List Flag -> Int -> restFns5 -> restStates4 -> List Flag
, fns :
Path
-> ( { baseUpdate :
Float -> Delta () -> State () -> ( State (), Cmd (Delta ()) )
, childViews :
ViewConfigStatic -> ViewConfigDynamic () -> List (Html (Delta ()))
, class : List String
, collectDebouncingReceivers : State () -> List Flag
, collectErrors : State () -> List Flag -> List ( String, String )
, emitFlags : State () -> List Flag
, id : Maybe String
, index : Int
, init : ( State (), Cmd (Delta ()) )
, initWith : output8 -> ( State (), Cmd (Delta ()) )
, label : Maybe String
, name : Maybe String
, parse : State () -> Result (List ( String, String )) output8
, path : Path
, receiverCount : Int
, setAllIdle : State () -> State ()
, subscriptions : State () -> Sub (Delta ())
, update : Delta () -> State () -> ( State (), Cmd (Delta ()) )
, view : ViewConfigStatic -> ViewConfigDynamic () -> Html (Delta ())
}
, a17
)
-> c6
, idleSetter : a16 -> Int -> restFns4 -> restStates3 -> restStates3
, index : Int
, initialDeltas : Path -> ( Cmd (Delta ()), a15 ) -> c5
, initialStates : Path -> ( State (), a14 ) -> c4
, initialiseDeltas : a13 -> List (Cmd msg1) -> f -> g -> h
, labels : List String
, makeDeltaSetters : a11 -> befores1 -> afters1 -> next
, makeStateSetters :
a10
-> ( (Int -> Int -> (End -> state3) -> End -> End -> State state3)
-> Int
-> Int
-> (c3 -> c3)
-> ( Maybe (State argState1), restMaybeArgStates1 )
-> ( State argState1, restInits )
-> State tagStates1
)
-> ( State argState1, restInits )
-> restFns3
-> restToArgStates
-> befores
-> afters
-> restStateSetters
, parser :
a9
-> Result (List ( String, String )) output2
-> Int
-> restFns2
-> restStates2
-> Result (List ( String, String )) output2
, stateAfter : i
, stateAfters : j
, stateBefore : ( Maybe a24, a7 ) -> c2
, stateBefores : ( ( Maybe a24, a7 ) -> c2, a6 ) -> c1
, stateInserter :
a5
-> Int
-> Int
-> (restArgStates -> tagStates)
-> restMaybeArgStates
-> restArgStates
-> State tagStates
, subscriptionCollector : a4 -> List (Sub msg) -> k -> l -> m -> n
, toArgStates : ( (output8 -> o) -> o, a2 ) -> c
, updater :
a1
-> { newCmds : List (Cmd recordDelta)
, newStates : restStates1 -> recordState0
}
-> restFns1
-> restDeltaSetters
-> restDeltas
-> restStates1
-> { newCmds : List (Cmd recordDelta)
, newStates : recordState1
}
, viewer :
a
-> Maybe (Html delta1)
-> List Flag
-> Int
-> restFns
-> restSetters
-> restStates
-> Maybe (Html delta1)
}
r
{ applyInputs :
a23
-> (stateSetter1 -> state0)
-> ( stateSetter1, restStateSetters1 )
-> state1_1
, debouncingReceiverCollector :
a22
-> List Flag
-> ( ControlFns input6 state7 delta9 output7, restFns7 )
-> ( State state7, restStates6 )
-> List Flag
, deltaAfter : ( Delta delta8, b )
, deltaAfters : ( b, d )
, deltaBefore : a21 -> c8
, deltaBefores : a20 -> c7
, destructor : e
, errorCollector :
a19
-> List Flag
-> List ( String, String )
-> ( ControlFns input5 state6 delta7 output6, restFns6 )
-> ( State state6, restStates5 )
-> List ( String, String )
, flagEmitter :
a18
-> List Flag
-> Int
-> ( ControlFns input4 state5 delta6 output5, restFns5 )
-> ( State state5, restStates4 )
-> List Flag
, fns : Path -> a17 -> c6
, idleSetter :
a16
-> Int
-> ( ControlFns input3 state4 delta5 output4, restFns4 )
-> ( State state4, restStates3 )
-> ( State state4, restStates3 )
, index : Int
, initialDeltas : Path -> a15 -> c5
, initialStates : Path -> a14 -> c4
, initialiseDeltas :
a13 -> List (Cmd msg1) -> ( a12 -> msg1, f ) -> ( Cmd a12, g ) -> h
, labels : List String
, makeDeltaSetters :
a11
-> ( ( value, after1 ) -> delta4, befores1 )
-> ( after1, afters1 )
-> ( value -> delta4, next )
, makeStateSetters :
a10
-> ( (Int -> Int -> (End -> state3) -> End -> End -> State state3)
-> Int
-> Int
-> (c3 -> c3)
-> ( Maybe (State argState1), restMaybeArgStates1 )
-> ( State argState1, restInits )
-> State tagStates1
)
-> ( State argState1, restInits )
-> ( ControlFns fieldInput fieldState delta3 output3, restFns3 )
-> ( (fieldInput -> State tagStates1) -> stateSetter
, restToArgStates
)
-> ( ( Maybe (State fieldState), after )
-> ( Maybe (State argState1), restMaybeArgStates1 )
, befores
)
-> ( after, afters )
-> ( stateSetter, restStateSetters )
, parser :
a9
-> Result (List ( String, String )) output2
-> Int
-> ( ControlFns input2 state2 delta2 output2, restFns2 )
-> ( State state2, restStates2 )
-> Result (List ( String, String )) output2
, stateAfter : ( Maybe a8, i )
, stateAfters : ( i, j )
, stateBefore : a7 -> c2
, stateBefores : a6 -> c1
, stateInserter :
a5
-> Int
-> Int
-> (( State argState, restArgStates ) -> tagStates)
-> ( Maybe (State argState), restMaybeArgStates )
-> ( State argState, restArgStates )
-> State tagStates
, subscriptionCollector :
a4
-> List (Sub msg)
-> ( a3 -> msg, k )
-> ( { s | subscriptions : q -> Sub a3 }, l )
-> ( q, m )
-> n
, toArgStates : a2 -> c
, updater :
a1
-> { newCmds : List (Cmd recordDelta)
, newStates : ( State state1, restStates1 ) -> recordState0
}
-> ( ControlFns input1 state1 delta output1, restFns1 )
-> ( Delta delta -> recordDelta, restDeltaSetters )
-> ( Delta delta, restDeltas )
-> ( State state1, restStates1 )
-> { newCmds : List (Cmd recordDelta)
, newStates : recordState1
}
, viewer :
a
-> Maybe (Html delta1)
-> List Flag
-> Int
-> ( ControlFns input state delta0 output, restFns )
-> ( Delta delta0 -> delta1, restSetters )
-> ( State state, restStates )
-> Maybe (Html delta1)
}

Add a tag with no arguments to a custom type.

type Unit
    = Unit


unitControl =
    customType
        (\unit tag ->
            case tag of
                Unit ->
                    unit
        )
        |> tag0 "Unit"
        |> end
String
-> (output9 -> output8)
-> AdvancedControl output9 state8 delta10 output9
r
{ s
| applyInputs : a23 -> state0 -> restStateSetters1 -> state1_1
, debouncingReceiverCollector :
a22 -> List Flag -> restFns7 -> restStates6 -> List Flag
, deltaAfter : d
, deltaAfters : e
, deltaBefore : ( Delta delta11, a21 ) -> c8
, deltaBefores : ( ( Delta delta11, a21 ) -> c8, a20 ) -> c7
, destructor : f
, errorCollector :
a19
-> List Flag
-> List ( String, String )
-> restFns6
-> restStates5
-> List ( String, String )
, flagEmitter :
a18 -> List Flag -> Int -> restFns5 -> restStates4 -> List Flag
, fns :
Path
-> ( { baseUpdate :
Float
-> Delta ( Delta delta10, End )
-> State ( State state8, End )
-> ( State ( State state8, End )
, Cmd (Delta ( Delta delta10, End ))
)
, childViews :
ViewConfigStatic
-> ViewConfigDynamic ( State state8, End )
-> List (Html (Delta ( Delta delta10, End )))
, class : List String
, collectDebouncingReceivers :
State ( State state8, End ) -> List Flag
, collectErrors :
State ( State state8, End ) -> List Flag -> List ( String, String )
, emitFlags : State ( State state8, End ) -> List Flag
, id : Maybe String
, index : Int
, init :
( State ( State state8, End )
, Cmd (Delta ( Delta delta10, End ))
)
, initWith :
( output9, b )
-> ( State ( State state8, End )
, Cmd (Delta ( Delta delta10, End ))
)
, label : Maybe String
, name : Maybe String
, parse :
State ( State state8, End )
-> Result (List ( String, String )) output8
, path : Path
, receiverCount : Int
, setAllIdle :
State ( State state8, End ) -> State ( State state8, End )
, subscriptions :
State ( State state8, End ) -> Sub (Delta ( Delta delta10, End ))
, update :
Delta ( Delta delta10, End )
-> State ( State state8, End )
-> ( State ( State state8, End )
, Cmd (Delta ( Delta delta10, End ))
)
, view :
ViewConfigStatic
-> ViewConfigDynamic ( State state8, End )
-> Html (Delta ( Delta delta10, End ))
}
, a17
)
-> c6
, idleSetter : a16 -> Int -> restFns4 -> restStates3 -> restStates3
, index : Int
, initialDeltas :
Path -> ( Cmd (Delta ( Delta delta10, End )), a15 ) -> c5
, initialStates : Path -> ( State ( State state8, End ), a14 ) -> c4
, initialiseDeltas : a13 -> List (Cmd msg1) -> g -> h -> i
, labels : List String
, makeDeltaSetters : a11 -> befores1 -> afters1 -> next
, makeStateSetters :
a10
-> ( (Int -> Int -> (End -> state3) -> End -> End -> State state3)
-> Int
-> Int
-> (c3 -> c3)
-> ( Maybe (State argState1), restMaybeArgStates1 )
-> ( State argState1, restInits )
-> State tagStates1
)
-> ( State argState1, restInits )
-> restFns3
-> restToArgStates
-> befores
-> afters
-> restStateSetters
, parser :
a9
-> Result (List ( String, String )) output2
-> Int
-> restFns2
-> restStates2
-> Result (List ( String, String )) output2
, stateAfter : j
, stateAfters : k
, stateBefore : ( Maybe a24, a7 ) -> c2
, stateBefores : ( ( Maybe a24, a7 ) -> c2, a6 ) -> c1
, stateInserter :
a5
-> Int
-> Int
-> (restArgStates -> tagStates)
-> restMaybeArgStates
-> restArgStates
-> State tagStates
, subscriptionCollector : a4 -> List (Sub msg) -> l -> m -> n -> o
, toArgStates : ( (( p, End ) -> q) -> p -> q, a2 ) -> c
, updater :
a1
-> { newCmds : List (Cmd recordDelta)
, newStates : restStates1 -> recordState0
}
-> restFns1
-> restDeltaSetters
-> restDeltas
-> restStates1
-> { newCmds : List (Cmd recordDelta)
, newStates : recordState1
}
, viewer :
a
-> Maybe (Html delta1)
-> List Flag
-> Int
-> restFns
-> restSetters
-> restStates
-> Maybe (Html delta1)
}
r
{ applyInputs :
a23
-> (stateSetter1 -> state0)
-> ( stateSetter1, restStateSetters1 )
-> state1_1
, debouncingReceiverCollector :
a22
-> List Flag
-> ( ControlFns input6 state7 delta9 output7, restFns7 )
-> ( State state7, restStates6 )
-> List Flag
, deltaAfter : ( Delta delta8, d )
, deltaAfters : ( d, e )
, deltaBefore : a21 -> c8
, deltaBefores : a20 -> c7
, destructor : f
, errorCollector :
a19
-> List Flag
-> List ( String, String )
-> ( ControlFns input5 state6 delta7 output6, restFns6 )
-> ( State state6, restStates5 )
-> List ( String, String )
, flagEmitter :
a18
-> List Flag
-> Int
-> ( ControlFns input4 state5 delta6 output5, restFns5 )
-> ( State state5, restStates4 )
-> List Flag
, fns : Path -> a17 -> c6
, idleSetter :
a16
-> Int
-> ( ControlFns input3 state4 delta5 output4, restFns4 )
-> ( State state4, restStates3 )
-> ( State state4, restStates3 )
, index : Int
, initialDeltas : Path -> a15 -> c5
, initialStates : Path -> a14 -> c4
, initialiseDeltas :
a13 -> List (Cmd msg1) -> ( a12 -> msg1, g ) -> ( Cmd a12, h ) -> i
, labels : List String
, makeDeltaSetters :
a11
-> ( ( value, after1 ) -> delta4, befores1 )
-> ( after1, afters1 )
-> ( value -> delta4, next )
, makeStateSetters :
a10
-> ( (Int -> Int -> (End -> state3) -> End -> End -> State state3)
-> Int
-> Int
-> (c3 -> c3)
-> ( Maybe (State argState1), restMaybeArgStates1 )
-> ( State argState1, restInits )
-> State tagStates1
)
-> ( State argState1, restInits )
-> ( ControlFns fieldInput fieldState delta3 output3, restFns3 )
-> ( (fieldInput -> State tagStates1) -> stateSetter
, restToArgStates
)
-> ( ( Maybe (State fieldState), after )
-> ( Maybe (State argState1), restMaybeArgStates1 )
, befores
)
-> ( after, afters )
-> ( stateSetter, restStateSetters )
, parser :
a9
-> Result (List ( String, String )) output2
-> Int
-> ( ControlFns input2 state2 delta2 output2, restFns2 )
-> ( State state2, restStates2 )
-> Result (List ( String, String )) output2
, stateAfter : ( Maybe a8, j )
, stateAfters : ( j, k )
, stateBefore : a7 -> c2
, stateBefores : a6 -> c1
, stateInserter :
a5
-> Int
-> Int
-> (( State argState, restArgStates ) -> tagStates)
-> ( Maybe (State argState), restMaybeArgStates )
-> ( State argState, restArgStates )
-> State tagStates
, subscriptionCollector :
a4
-> List (Sub msg)
-> ( a3 -> msg, l )
-> ( { u | subscriptions : t -> Sub a3 }, m )
-> ( t, n )
-> o
, toArgStates : a2 -> c
, updater :
a1
-> { newCmds : List (Cmd recordDelta)
, newStates : ( State state1, restStates1 ) -> recordState0
}
-> ( ControlFns input1 state1 delta output1, restFns1 )
-> ( Delta delta -> recordDelta, restDeltaSetters )
-> ( Delta delta, restDeltas )
-> ( State state1, restStates1 )
-> { newCmds : List (Cmd recordDelta)
, newStates : recordState1
}
, viewer :
a
-> Maybe (Html delta1)
-> List Flag
-> Int
-> ( ControlFns input state delta0 output, restFns )
-> ( Delta delta0 -> delta1, restSetters )
-> ( State state, restStates )
-> Maybe (Html delta1)
}

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
        |> end
String
-> (output10 -> output9 -> output8)
-> ( String, AdvancedControl output10 state9 delta11 output10 )
-> ( String, AdvancedControl output9 state8 delta10 output9 )
r
{ t
| applyInputs : a23 -> state0 -> restStateSetters1 -> state1_1
, debouncingReceiverCollector :
a22 -> List Flag -> restFns7 -> restStates6 -> List Flag
, deltaAfter : d
, deltaAfters : e
, deltaBefore : ( Delta delta12, a21 ) -> c8
, deltaBefores : ( ( Delta delta12, a21 ) -> c8, a20 ) -> c7
, destructor : f
, errorCollector :
a19
-> List Flag
-> List ( String, String )
-> restFns6
-> restStates5
-> List ( String, String )
, flagEmitter :
a18 -> List Flag -> Int -> restFns5 -> restStates4 -> List Flag
, fns :
Path
-> ( { baseUpdate :
Float
-> Delta ( Delta delta11, ( Delta delta10, End ) )
-> State ( State state9, ( State state8, End ) )
-> ( State ( State state9, ( State state8, End ) )
, Cmd (Delta ( Delta delta11, ( Delta delta10, End ) ))
)
, childViews :
ViewConfigStatic
-> ViewConfigDynamic ( State state9, ( State state8, End ) )
-> List (Html (Delta ( Delta delta11, ( Delta delta10, End ) )))
, class : List String
, collectDebouncingReceivers :
State ( State state9, ( State state8, End ) ) -> List Flag
, collectErrors :
State ( State state9, ( State state8, End ) )
-> List Flag
-> List ( String, String )
, emitFlags :
State ( State state9, ( State state8, End ) ) -> List Flag
, id : Maybe String
, index : Int
, init :
( State ( State state9, ( State state8, End ) )
, Cmd (Delta ( Delta delta11, ( Delta delta10, End ) ))
)
, initWith :
( output10, ( output9, b ) )
-> ( State ( State state9, ( State state8, End ) )
, Cmd (Delta ( Delta delta11, ( Delta delta10, End ) ))
)
, label : Maybe String
, name : Maybe String
, parse :
State ( State state9, ( State state8, End ) )
-> Result (List ( String, String )) output8
, path : Path
, receiverCount : Int
, setAllIdle :
State ( State state9, ( State state8, End ) )
-> State ( State state9, ( State state8, End ) )
, subscriptions :
State ( State state9, ( State state8, End ) )
-> Sub (Delta ( Delta delta11, ( Delta delta10, End ) ))
, update :
Delta ( Delta delta11, ( Delta delta10, End ) )
-> State ( State state9, ( State state8, End ) )
-> ( State ( State state9, ( State state8, End ) )
, Cmd (Delta ( Delta delta11, ( Delta delta10, End ) ))
)
, view :
ViewConfigStatic
-> ViewConfigDynamic ( State state9, ( State state8, End ) )
-> Html (Delta ( Delta delta11, ( Delta delta10, End ) ))
}
, a17
)
-> c6
, idleSetter : a16 -> Int -> restFns4 -> restStates3 -> restStates3
, index : Int
, initialDeltas :
Path
-> ( Cmd (Delta ( Delta delta11, ( Delta delta10, End ) )), a15 )
-> c5
, initialStates :
Path
-> ( State ( State state9, ( State state8, End ) ), a14 )
-> c4
, initialiseDeltas : a13 -> List (Cmd msg1) -> g -> h -> i
, labels : List String
, makeDeltaSetters : a11 -> befores1 -> afters1 -> next
, makeStateSetters :
a10
-> ( (Int -> Int -> (End -> state3) -> End -> End -> State state3)
-> Int
-> Int
-> (c3 -> c3)
-> ( Maybe (State argState1), restMaybeArgStates1 )
-> ( State argState1, restInits )
-> State tagStates1
)
-> ( State argState1, restInits )
-> restFns3
-> restToArgStates
-> befores
-> afters
-> restStateSetters
, parser :
a9
-> Result (List ( String, String )) output2
-> Int
-> restFns2
-> restStates2
-> Result (List ( String, String )) output2
, stateAfter : j
, stateAfters : k
, stateBefore : ( Maybe a24, a7 ) -> c2
, stateBefores : ( ( Maybe a24, a7 ) -> c2, a6 ) -> c1
, stateInserter :
a5
-> Int
-> Int
-> (restArgStates -> tagStates)
-> restMaybeArgStates
-> restArgStates
-> State tagStates
, subscriptionCollector : a4 -> List (Sub msg) -> l -> m -> n -> o
, toArgStates : ( (( p, ( q, End ) ) -> s) -> p -> q -> s, a2 ) -> c
, updater :
a1
-> { newCmds : List (Cmd recordDelta)
, newStates : restStates1 -> recordState0
}
-> restFns1
-> restDeltaSetters
-> restDeltas
-> restStates1
-> { newCmds : List (Cmd recordDelta)
, newStates : recordState1
}
, viewer :
a
-> Maybe (Html delta1)
-> List Flag
-> Int
-> restFns
-> restSetters
-> restStates
-> Maybe (Html delta1)
}
r
{ applyInputs :
a23
-> (stateSetter1 -> state0)
-> ( stateSetter1, restStateSetters1 )
-> state1_1
, debouncingReceiverCollector :
a22
-> List Flag
-> ( ControlFns input6 state7 delta9 output7, restFns7 )
-> ( State state7, restStates6 )
-> List Flag
, deltaAfter : ( Delta delta8, d )
, deltaAfters : ( d, e )
, deltaBefore : a21 -> c8
, deltaBefores : a20 -> c7
, destructor : f
, errorCollector :
a19
-> List Flag
-> List ( String, String )
-> ( ControlFns input5 state6 delta7 output6, restFns6 )
-> ( State state6, restStates5 )
-> List ( String, String )
, flagEmitter :
a18
-> List Flag
-> Int
-> ( ControlFns input4 state5 delta6 output5, restFns5 )
-> ( State state5, restStates4 )
-> List Flag
, fns : Path -> a17 -> c6
, idleSetter :
a16
-> Int
-> ( ControlFns input3 state4 delta5 output4, restFns4 )
-> ( State state4, restStates3 )
-> ( State state4, restStates3 )
, index : Int
, initialDeltas : Path -> a15 -> c5
, initialStates : Path -> a14 -> c4
, initialiseDeltas :
a13 -> List (Cmd msg1) -> ( a12 -> msg1, g ) -> ( Cmd a12, h ) -> i
, labels : List String
, makeDeltaSetters :
a11
-> ( ( value, after1 ) -> delta4, befores1 )
-> ( after1, afters1 )
-> ( value -> delta4, next )
, makeStateSetters :
a10
-> ( (Int -> Int -> (End -> state3) -> End -> End -> State state3)
-> Int
-> Int
-> (c3 -> c3)
-> ( Maybe (State argState1), restMaybeArgStates1 )
-> ( State argState1, restInits )
-> State tagStates1
)
-> ( State argState1, restInits )
-> ( ControlFns fieldInput fieldState delta3 output3, restFns3 )
-> ( (fieldInput -> State tagStates1) -> stateSetter
, restToArgStates
)
-> ( ( Maybe (State fieldState), after )
-> ( Maybe (State argState1), restMaybeArgStates1 )
, befores
)
-> ( after, afters )
-> ( stateSetter, restStateSetters )
, parser :
a9
-> Result (List ( String, String )) output2
-> Int
-> ( ControlFns input2 state2 delta2 output2, restFns2 )
-> ( State state2, restStates2 )
-> Result (List ( String, String )) output2
, stateAfter : ( Maybe a8, j )
, stateAfters : ( j, k )
, stateBefore : a7 -> c2
, stateBefores : a6 -> c1
, stateInserter :
a5
-> Int
-> Int
-> (( State argState, restArgStates ) -> tagStates)
-> ( Maybe (State argState), restMaybeArgStates )
-> ( State argState, restArgStates )
-> State tagStates
, subscriptionCollector :
a4
-> List (Sub msg)
-> ( a3 -> msg, l )
-> ( { v | subscriptions : u -> Sub a3 }, m )
-> ( u, n )
-> o
, toArgStates : a2 -> c
, updater :
a1
-> { newCmds : List (Cmd recordDelta)
, newStates : ( State state1, restStates1 ) -> recordState0
}
-> ( ControlFns input1 state1 delta output1, restFns1 )
-> ( Delta delta -> recordDelta, restDeltaSetters )
-> ( Delta delta, restDeltas )
-> ( State state1, restStates1 )
-> { newCmds : List (Cmd recordDelta)
, newStates : recordState1
}
, viewer :
a
-> Maybe (Html delta1)
-> List Flag
-> Int
-> ( ControlFns input state delta0 output, restFns )
-> ( Delta delta0 -> delta1, restSetters )
-> ( State state, restStates )
-> Maybe (Html delta1)
}

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 ( "X", float ) ( "Y", float )
String
-> (output11 -> output10 -> output9 -> output8)
-> ( String, AdvancedControl output11 state10 delta12 output11 )
-> ( String, AdvancedControl output10 state9 delta11 output10 )
-> ( String, AdvancedControl output9 state8 delta10 output9 )
r
{ u
| applyInputs : a23 -> state0 -> restStateSetters1 -> state1_1
, debouncingReceiverCollector :
a22 -> List Flag -> restFns7 -> restStates6 -> List Flag
, deltaAfter : d
, deltaAfters : e
, deltaBefore : ( Delta delta13, a21 ) -> c8
, deltaBefores : ( ( Delta delta13, a21 ) -> c8, a20 ) -> c7
, destructor : f
, errorCollector :
a19
-> List Flag
-> List ( String, String )
-> restFns6
-> restStates5
-> List ( String, String )
, flagEmitter :
a18 -> List Flag -> Int -> restFns5 -> restStates4 -> List Flag
, fns :
Path
-> ( { baseUpdate :
Float
-> Delta
( Delta delta12, ( Delta delta11, ( Delta delta10, End ) ) )
-> State
( State state10, ( State state9, ( State state8, End ) ) )
-> ( State
( State state10, ( State state9, ( State state8, End ) ) )
, Cmd
( Delta delta12, ( Delta delta11, ( Delta delta10, End ) ) )
)
)
, childViews :
ViewConfigStatic
-> ViewConfigDynamic
( State state10, ( State state9, ( State state8, End ) ) )
-> List
(Html
( Delta delta12, ( Delta delta11, ( Delta delta10, End ) ) )
)
)
, class : List String
, collectDebouncingReceivers :
( State state10, ( State state9, ( State state8, End ) ) )
-> List Flag
, collectErrors :
( State state10, ( State state9, ( State state8, End ) ) )
-> List Flag
-> List ( String, String )
, emitFlags :
( State state10, ( State state9, ( State state8, End ) ) )
-> List Flag
, id : Maybe String
, index : Int
, init :
( State state10, ( State state9, ( State state8, End ) ) )
, Cmd
( Delta delta12, ( Delta delta11, ( Delta delta10, End ) ) )
)
)
, initWith :
( output11, ( output10, ( output9, b ) ) )
-> ( State
( State state10, ( State state9, ( State state8, End ) ) )
, Cmd
( Delta delta12, ( Delta delta11, ( Delta delta10, End ) ) )
)
)
, label : Maybe String
, name : Maybe String
, parse :
( State state10, ( State state9, ( State state8, End ) ) )
-> Result (List ( String, String )) output8
, path : Path
, receiverCount : Int
, setAllIdle :
( State state10, ( State state9, ( State state8, End ) ) )
-> State
( State state10, ( State state9, ( State state8, End ) ) )
, subscriptions :
( State state10, ( State state9, ( State state8, End ) ) )
-> Sub
( Delta delta12, ( Delta delta11, ( Delta delta10, End ) ) )
)
, update :
( Delta delta12, ( Delta delta11, ( Delta delta10, End ) ) )
-> State
( State state10, ( State state9, ( State state8, End ) ) )
-> ( State
( State state10, ( State state9, ( State state8, End ) ) )
, Cmd
( Delta delta12, ( Delta delta11, ( Delta delta10, End ) ) )
)
)
, view :
ViewConfigStatic
-> ViewConfigDynamic
( State state10, ( State state9, ( State state8, End ) ) )
-> Html
( Delta delta12, ( Delta delta11, ( Delta delta10, End ) ) )
)
}
, a17
)
-> c6
, idleSetter : a16 -> Int -> restFns4 -> restStates3 -> restStates3
, index : Int
, initialDeltas :
Path
-> ( Cmd
( Delta delta12, ( Delta delta11, ( Delta delta10, End ) ) )
)
, a15
)
-> c5
, initialStates :
Path
-> ( State
( State state10, ( State state9, ( State state8, End ) ) )
, a14
)
-> c4
, initialiseDeltas : a13 -> List (Cmd msg1) -> g -> h -> i
, labels : List String
, makeDeltaSetters : a11 -> befores1 -> afters1 -> next
, makeStateSetters :
a10
-> ( (Int -> Int -> (End -> state3) -> End -> End -> State state3)
-> Int
-> Int
-> (c3 -> c3)
-> ( Maybe (State argState1), restMaybeArgStates1 )
-> ( State argState1, restInits )
-> State tagStates1
)
-> ( State argState1, restInits )
-> restFns3
-> restToArgStates
-> befores
-> afters
-> restStateSetters
, parser :
a9
-> Result (List ( String, String )) output2
-> Int
-> restFns2
-> restStates2
-> Result (List ( String, String )) output2
, stateAfter : j
, stateAfters : k
, stateBefore : ( Maybe a24, a7 ) -> c2
, stateBefores : ( ( Maybe a24, a7 ) -> c2, a6 ) -> c1
, stateInserter :
a5
-> Int
-> Int
-> (restArgStates -> tagStates)
-> restMaybeArgStates
-> restArgStates
-> State tagStates
, subscriptionCollector : a4 -> List (Sub msg) -> l -> m -> n -> o
, toArgStates :
( (( p, ( q, ( s, End ) ) ) -> t) -> p -> q -> s -> t, a2 ) -> c
, updater :
a1
-> { newCmds : List (Cmd recordDelta)
, newStates : restStates1 -> recordState0
}
-> restFns1
-> restDeltaSetters
-> restDeltas
-> restStates1
-> { newCmds : List (Cmd recordDelta)
, newStates : recordState1
}
, viewer :
a
-> Maybe (Html delta1)
-> List Flag
-> Int
-> restFns
-> restSetters
-> restStates
-> Maybe (Html delta1)
}
r
{ applyInputs :
a23
-> (stateSetter1 -> state0)
-> ( stateSetter1, restStateSetters1 )
-> state1_1
, debouncingReceiverCollector :
a22
-> List Flag
-> ( ControlFns input6 state7 delta9 output7, restFns7 )
-> ( State state7, restStates6 )
-> List Flag
, deltaAfter : ( Delta delta8, d )
, deltaAfters : ( d, e )
, deltaBefore : a21 -> c8
, deltaBefores : a20 -> c7
, destructor : f
, errorCollector :
a19
-> List Flag
-> List ( String, String )
-> ( ControlFns input5 state6 delta7 output6, restFns6 )
-> ( State state6, restStates5 )
-> List ( String, String )
, flagEmitter :
a18
-> List Flag
-> Int
-> ( ControlFns input4 state5 delta6 output5, restFns5 )
-> ( State state5, restStates4 )
-> List Flag
, fns : Path -> a17 -> c6
, idleSetter :
a16
-> Int
-> ( ControlFns input3 state4 delta5 output4, restFns4 )
-> ( State state4, restStates3 )
-> ( State state4, restStates3 )
, index : Int
, initialDeltas : Path -> a15 -> c5
, initialStates : Path -> a14 -> c4
, initialiseDeltas :
a13 -> List (Cmd msg1) -> ( a12 -> msg1, g ) -> ( Cmd a12, h ) -> i
, labels : List String
, makeDeltaSetters :
a11
-> ( ( value, after1 ) -> delta4, befores1 )
-> ( after1, afters1 )
-> ( value -> delta4, next )
, makeStateSetters :
a10
-> ( (Int -> Int -> (End -> state3) -> End -> End -> State state3)
-> Int
-> Int
-> (c3 -> c3)
-> ( Maybe (State argState1), restMaybeArgStates1 )
-> ( State argState1, restInits )
-> State tagStates1
)
-> ( State argState1, restInits )
-> ( ControlFns fieldInput fieldState delta3 output3, restFns3 )
-> ( (fieldInput -> State tagStates1) -> stateSetter
, restToArgStates
)
-> ( ( Maybe (State fieldState), after )
-> ( Maybe (State argState1), restMaybeArgStates1 )
, befores
)
-> ( after, afters )
-> ( stateSetter, restStateSetters )
, parser :
a9
-> Result (List ( String, String )) output2
-> Int
-> ( ControlFns input2 state2 delta2 output2, restFns2 )
-> ( State state2, restStates2 )
-> Result (List ( String, String )) output2
, stateAfter : ( Maybe a8, j )
, stateAfters : ( j, k )
, stateBefore : a7 -> c2
, stateBefores : a6 -> c1
, stateInserter :
a5
-> Int
-> Int
-> (( State argState, restArgStates ) -> tagStates)
-> ( Maybe (State argState), restMaybeArgStates )
-> ( State argState, restArgStates )
-> State tagStates
, subscriptionCollector :
a4
-> List (Sub msg)
-> ( a3 -> msg, l )
-> ( { w | subscriptions : v -> Sub a3 }, m )
-> ( v, n )
-> o
, toArgStates : a2 -> c
, updater :
a1
-> { newCmds : List (Cmd recordDelta)
, newStates : ( State state1, restStates1 ) -> recordState0
}
-> ( ControlFns input1 state1 delta output1, restFns1 )
-> ( Delta delta -> recordDelta, restDeltaSetters )
-> ( Delta delta, restDeltas )
-> ( State state1, restStates1 )
-> { newCmds : List (Cmd recordDelta)
, newStates : recordState1
}
, viewer :
a
-> Maybe (Html delta1)
-> List Flag
-> Int
-> ( ControlFns input state delta0 output, restFns )
-> ( Delta delta0 -> delta1, restSetters )
-> ( State state, restStates )
-> Maybe (Html delta1)
}

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 ( "X", float ) ( "Y", float ) ( "Z", float )
String
-> (output12 -> output11 -> output10 -> output9 -> output8)
-> ( String, AdvancedControl output12 state11 delta13 output12 )
-> ( String, AdvancedControl output11 state10 delta12 output11 )
-> ( String, AdvancedControl output10 state9 delta11 output10 )
-> ( String, AdvancedControl output9 state8 delta10 output9 )
r
{ v
| applyInputs : a23 -> state0 -> restStateSetters1 -> state1_1
, debouncingReceiverCollector :
a22 -> List Flag -> restFns7 -> restStates6 -> List Flag
, deltaAfter : d
, deltaAfters : e
, deltaBefore : ( Delta delta14, a21 ) -> c8
, deltaBefores : ( ( Delta delta14, a21 ) -> c8, a20 ) -> c7
, destructor : f
, errorCollector :
a19
-> List Flag
-> List ( String, String )
-> restFns6
-> restStates5
-> List ( String, String )
, flagEmitter :
a18 -> List Flag -> Int -> restFns5 -> restStates4 -> List Flag
, fns :
Path
-> ( { baseUpdate :
Float
-> Delta
( Delta delta13
, ( Delta delta12, ( Delta delta11, ( Delta delta10, End ) ) )
)
-> State
( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
-> ( State
( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
, Cmd
( Delta delta13
, ( Delta delta12, ( Delta delta11, ( Delta delta10, End ) ) )
)
)
)
, childViews :
ViewConfigStatic
-> ViewConfigDynamic
( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
-> List
(Html
( Delta delta13
, ( Delta delta12, ( Delta delta11, ( Delta delta10, End ) ) )
)
)
)
, class : List String
, collectDebouncingReceivers :
( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
-> List Flag
, collectErrors :
( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
-> List Flag
-> List ( String, String )
, emitFlags :
( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
-> List Flag
, id : Maybe String
, index : Int
, init :
( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
, Cmd
( Delta delta13
, ( Delta delta12, ( Delta delta11, ( Delta delta10, End ) ) )
)
)
)
, initWith :
( output12, ( output11, ( output10, ( output9, b ) ) ) )
-> ( State
( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
, Cmd
( Delta delta13
, ( Delta delta12, ( Delta delta11, ( Delta delta10, End ) ) )
)
)
)
, label : Maybe String
, name : Maybe String
, parse :
( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
-> Result (List ( String, String )) output8
, path : Path
, receiverCount : Int
, setAllIdle :
( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
-> State
( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
, subscriptions :
( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
-> Sub
( Delta delta13
, ( Delta delta12, ( Delta delta11, ( Delta delta10, End ) ) )
)
)
, update :
( Delta delta13
, ( Delta delta12, ( Delta delta11, ( Delta delta10, End ) ) )
)
-> State
( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
-> ( State
( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
, Cmd
( Delta delta13
, ( Delta delta12, ( Delta delta11, ( Delta delta10, End ) ) )
)
)
)
, view :
ViewConfigStatic
-> ViewConfigDynamic
( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
-> Html
( Delta delta13
, ( Delta delta12, ( Delta delta11, ( Delta delta10, End ) ) )
)
)
}
, a17
)
-> c6
, idleSetter : a16 -> Int -> restFns4 -> restStates3 -> restStates3
, index : Int
, initialDeltas :
Path
-> ( Cmd
( Delta delta13
, ( Delta delta12, ( Delta delta11, ( Delta delta10, End ) ) )
)
)
, a15
)
-> c5
, initialStates :
Path
-> ( State
( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
, a14
)
-> c4
, initialiseDeltas : a13 -> List (Cmd msg1) -> g -> h -> i
, labels : List String
, makeDeltaSetters : a11 -> befores1 -> afters1 -> next
, makeStateSetters :
a10
-> ( (Int -> Int -> (End -> state3) -> End -> End -> State state3)
-> Int
-> Int
-> (c3 -> c3)
-> ( Maybe (State argState1), restMaybeArgStates1 )
-> ( State argState1, restInits )
-> State tagStates1
)
-> ( State argState1, restInits )
-> restFns3
-> restToArgStates
-> befores
-> afters
-> restStateSetters
, parser :
a9
-> Result (List ( String, String )) output2
-> Int
-> restFns2
-> restStates2
-> Result (List ( String, String )) output2
, stateAfter : j
, stateAfters : k
, stateBefore : ( Maybe a24, a7 ) -> c2
, stateBefores : ( ( Maybe a24, a7 ) -> c2, a6 ) -> c1
, stateInserter :
a5
-> Int
-> Int
-> (restArgStates -> tagStates)
-> restMaybeArgStates
-> restArgStates
-> State tagStates
, subscriptionCollector : a4 -> List (Sub msg) -> l -> m -> n -> o
, toArgStates :
( (( p, ( q, ( s, ( t, End ) ) ) ) -> u) -> p -> q -> s -> t -> u, a2 ) -> c
, updater :
a1
-> { newCmds : List (Cmd recordDelta)
, newStates : restStates1 -> recordState0
}
-> restFns1
-> restDeltaSetters
-> restDeltas
-> restStates1
-> { newCmds : List (Cmd recordDelta)
, newStates : recordState1
}
, viewer :
a
-> Maybe (Html delta1)
-> List Flag
-> Int
-> restFns
-> restSetters
-> restStates
-> Maybe (Html delta1)
}
r
{ applyInputs :
a23
-> (stateSetter1 -> state0)
-> ( stateSetter1, restStateSetters1 )
-> state1_1
, debouncingReceiverCollector :
a22
-> List Flag
-> ( ControlFns input6 state7 delta9 output7, restFns7 )
-> ( State state7, restStates6 )
-> List Flag
, deltaAfter : ( Delta delta8, d )
, deltaAfters : ( d, e )
, deltaBefore : a21 -> c8
, deltaBefores : a20 -> c7
, destructor : f
, errorCollector :
a19
-> List Flag
-> List ( String, String )
-> ( ControlFns input5 state6 delta7 output6, restFns6 )
-> ( State state6, restStates5 )
-> List ( String, String )
, flagEmitter :
a18
-> List Flag
-> Int
-> ( ControlFns input4 state5 delta6 output5, restFns5 )
-> ( State state5, restStates4 )
-> List Flag
, fns : Path -> a17 -> c6
, idleSetter :
a16
-> Int
-> ( ControlFns input3 state4 delta5 output4, restFns4 )
-> ( State state4, restStates3 )
-> ( State state4, restStates3 )
, index : Int
, initialDeltas : Path -> a15 -> c5
, initialStates : Path -> a14 -> c4
, initialiseDeltas :
a13 -> List (Cmd msg1) -> ( a12 -> msg1, g ) -> ( Cmd a12, h ) -> i
, labels : List String
, makeDeltaSetters :
a11
-> ( ( value, after1 ) -> delta4, befores1 )
-> ( after1, afters1 )
-> ( value -> delta4, next )
, makeStateSetters :
a10
-> ( (Int -> Int -> (End -> state3) -> End -> End -> State state3)
-> Int
-> Int
-> (c3 -> c3)
-> ( Maybe (State argState1), restMaybeArgStates1 )
-> ( State argState1, restInits )
-> State tagStates1
)
-> ( State argState1, restInits )
-> ( ControlFns fieldInput fieldState delta3 output3, restFns3 )
-> ( (fieldInput -> State tagStates1) -> stateSetter
, restToArgStates
)
-> ( ( Maybe (State fieldState), after )
-> ( Maybe (State argState1), restMaybeArgStates1 )
, befores
)
-> ( after, afters )
-> ( stateSetter, restStateSetters )
, parser :
a9
-> Result (List ( String, String )) output2
-> Int
-> ( ControlFns input2 state2 delta2 output2, restFns2 )
-> ( State state2, restStates2 )
-> Result (List ( String, String )) output2
, stateAfter : ( Maybe a8, j )
, stateAfters : ( j, k )
, stateBefore : a7 -> c2
, stateBefores : a6 -> c1
, stateInserter :
a5
-> Int
-> Int
-> (( State argState, restArgStates ) -> tagStates)
-> ( Maybe (State argState), restMaybeArgStates )
-> ( State argState, restArgStates )
-> State tagStates
, subscriptionCollector :
a4
-> List (Sub msg)
-> ( a3 -> msg, l )
-> ( { x | subscriptions : w -> Sub a3 }, m )
-> ( w, n )
-> o
, toArgStates : a2 -> c
, updater :
a1
-> { newCmds : List (Cmd recordDelta)
, newStates : ( State state1, restStates1 ) -> recordState0
}
-> ( ControlFns input1 state1 delta output1, restFns1 )
-> ( Delta delta -> recordDelta, restDeltaSetters )
-> ( Delta delta, restDeltas )
-> ( State state1, restStates1 )
-> { newCmds : List (Cmd recordDelta)
, newStates : recordState1
}
, viewer :
a
-> Maybe (Html delta1)
-> List Flag
-> Int
-> ( ControlFns input state delta0 output, restFns )
-> ( Delta delta0 -> delta1, restSetters )
-> ( State state, restStates )
-> Maybe (Html delta1)
}

Add a tag with four arguments to a custom type.

String
-> (output13 -> output12 -> output11 -> output10 -> output9 -> output8)
-> ( String, AdvancedControl output13 state12 delta14 output13 )
-> ( String, AdvancedControl output12 state11 delta13 output12 )
-> ( String, AdvancedControl output11 state10 delta12 output11 )
-> ( String, AdvancedControl output10 state9 delta11 output10 )
-> ( String, AdvancedControl output9 state8 delta10 output9 )
r
{ w
| applyInputs : a23 -> state0 -> restStateSetters1 -> state1_1
, debouncingReceiverCollector :
a22 -> List Flag -> restFns7 -> restStates6 -> List Flag
, deltaAfter : d
, deltaAfters : e
, deltaBefore : ( Delta delta15, a21 ) -> c8
, deltaBefores : ( ( Delta delta15, a21 ) -> c8, a20 ) -> c7
, destructor : f
, errorCollector :
a19
-> List Flag
-> List ( String, String )
-> restFns6
-> restStates5
-> List ( String, String )
, flagEmitter :
a18 -> List Flag -> Int -> restFns5 -> restStates4 -> List Flag
, fns :
Path
-> ( { baseUpdate :
Float
-> Delta
( Delta delta14
, ( Delta delta13
, ( Delta delta12, ( Delta delta11, ( Delta delta10, End ) ) )
)
)
-> State
( State state12
, ( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
)
-> ( State
( State state12
, ( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
)
, Cmd
( Delta delta14
, ( Delta delta13
, ( Delta delta12, ( Delta delta11, ( Delta delta10, End ) ) )
)
)
)
)
, childViews :
ViewConfigStatic
-> ViewConfigDynamic
( State state12
, ( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
)
-> List
(Html
( Delta delta14
, ( Delta delta13
, ( Delta delta12, ( Delta delta11, ( Delta delta10, End ) ) )
)
)
)
)
, class : List String
, collectDebouncingReceivers :
( State state12
, ( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
)
-> List Flag
, collectErrors :
( State state12
, ( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
)
-> List Flag
-> List ( String, String )
, emitFlags :
( State state12
, ( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
)
-> List Flag
, id : Maybe String
, index : Int
, init :
( State state12
, ( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
)
, Cmd
( Delta delta14
, ( Delta delta13
, ( Delta delta12, ( Delta delta11, ( Delta delta10, End ) ) )
)
)
)
)
, initWith :
( output13
, ( output12, ( output11, ( output10, ( output9, b ) ) ) )
)
-> ( State
( State state12
, ( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
)
, Cmd
( Delta delta14
, ( Delta delta13
, ( Delta delta12, ( Delta delta11, ( Delta delta10, End ) ) )
)
)
)
)
, label : Maybe String
, name : Maybe String
, parse :
( State state12
, ( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
)
-> Result (List ( String, String )) output8
, path : Path
, receiverCount : Int
, setAllIdle :
( State state12
, ( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
)
-> State
( State state12
, ( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
)
, subscriptions :
( State state12
, ( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
)
-> Sub
( Delta delta14
, ( Delta delta13
, ( Delta delta12, ( Delta delta11, ( Delta delta10, End ) ) )
)
)
)
, update :
( Delta delta14
, ( Delta delta13
, ( Delta delta12, ( Delta delta11, ( Delta delta10, End ) ) )
)
)
-> State
( State state12
, ( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
)
-> ( State
( State state12
, ( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
)
, Cmd
( Delta delta14
, ( Delta delta13
, ( Delta delta12, ( Delta delta11, ( Delta delta10, End ) ) )
)
)
)
)
, view :
ViewConfigStatic
-> ViewConfigDynamic
( State state12
, ( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
)
-> Html
( Delta delta14
, ( Delta delta13
, ( Delta delta12, ( Delta delta11, ( Delta delta10, End ) ) )
)
)
)
}
, a17
)
-> c6
, idleSetter : a16 -> Int -> restFns4 -> restStates3 -> restStates3
, index : Int
, initialDeltas :
Path
-> ( Cmd
( Delta delta14
, ( Delta delta13
, ( Delta delta12, ( Delta delta11, ( Delta delta10, End ) ) )
)
)
)
, a15
)
-> c5
, initialStates :
Path
-> ( State
( State state12
, ( State state11
, ( State state10, ( State state9, ( State state8, End ) ) )
)
)
, a14
)
-> c4
, initialiseDeltas : a13 -> List (Cmd msg1) -> g -> h -> i
, labels : List String
, makeDeltaSetters : a11 -> befores1 -> afters1 -> next
, makeStateSetters :
a10
-> ( (Int -> Int -> (End -> state3) -> End -> End -> State state3)
-> Int
-> Int
-> (c3 -> c3)
-> ( Maybe (State argState1), restMaybeArgStates1 )
-> ( State argState1, restInits )
-> State tagStates1
)
-> ( State argState1, restInits )
-> restFns3
-> restToArgStates
-> befores
-> afters
-> restStateSetters
, parser :
a9
-> Result (List ( String, String )) output2
-> Int
-> restFns2
-> restStates2
-> Result (List ( String, String )) output2
, stateAfter : j
, stateAfters : k
, stateBefore : ( Maybe a24, a7 ) -> c2
, stateBefores : ( ( Maybe a24, a7 ) -> c2, a6 ) -> c1
, stateInserter :
a5
-> Int
-> Int
-> (restArgStates -> tagStates)
-> restMaybeArgStates
-> restArgStates
-> State tagStates
, subscriptionCollector : a4 -> List (Sub msg) -> l -> m -> n -> o
, toArgStates :
( (( p, ( q, ( s, ( t, ( u, End ) ) ) ) ) -> v) -> p -> q -> s -> t -> u -> v
, a2
)
-> c
, updater :
a1
-> { newCmds : List (Cmd recordDelta)
, newStates : restStates1 -> recordState0
}
-> restFns1
-> restDeltaSetters
-> restDeltas
-> restStates1
-> { newCmds : List (Cmd recordDelta)
, newStates : recordState1
}
, viewer :
a
-> Maybe (Html delta1)
-> List Flag
-> Int
-> restFns
-> restSetters
-> restStates
-> Maybe (Html delta1)
}
r
{ applyInputs :
a23
-> (stateSetter1 -> state0)
-> ( stateSetter1, restStateSetters1 )
-> state1_1
, debouncingReceiverCollector :
a22
-> List Flag
-> ( ControlFns input6 state7 delta9 output7, restFns7 )
-> ( State state7, restStates6 )
-> List Flag
, deltaAfter : ( Delta delta8, d )
, deltaAfters : ( d, e )
, deltaBefore : a21 -> c8
, deltaBefores : a20 -> c7
, destructor : f
, errorCollector :
a19
-> List Flag
-> List ( String, String )
-> ( ControlFns input5 state6 delta7 output6, restFns6 )
-> ( State state6, restStates5 )
-> List ( String, String )
, flagEmitter :
a18
-> List Flag
-> Int
-> ( ControlFns input4 state5 delta6 output5, restFns5 )
-> ( State state5, restStates4 )
-> List Flag
, fns : Path -> a17 -> c6
, idleSetter :
a16
-> Int
-> ( ControlFns input3 state4 delta5 output4, restFns4 )
-> ( State state4, restStates3 )
-> ( State state4, restStates3 )
, index : Int
, initialDeltas : Path -> a15 -> c5
, initialStates : Path -> a14 -> c4
, initialiseDeltas :
a13 -> List (Cmd msg1) -> ( a12 -> msg1, g ) -> ( Cmd a12, h ) -> i
, labels : List String
, makeDeltaSetters :
a11
-> ( ( value, after1 ) -> delta4, befores1 )
-> ( after1, afters1 )
-> ( value -> delta4, next )
, makeStateSetters :
a10
-> ( (Int -> Int -> (End -> state3) -> End -> End -> State state3)
-> Int
-> Int
-> (c3 -> c3)
-> ( Maybe (State argState1), restMaybeArgStates1 )
-> ( State argState1, restInits )
-> State tagStates1
)
-> ( State argState1, restInits )
-> ( ControlFns fieldInput fieldState delta3 output3, restFns3 )
-> ( (fieldInput -> State tagStates1) -> stateSetter
, restToArgStates
)
-> ( ( Maybe (State fieldState), after )
-> ( Maybe (State argState1), restMaybeArgStates1 )
, befores
)
-> ( after, afters )
-> ( stateSetter, restStateSetters )
, parser :
a9
-> Result (List ( String, String )) output2
-> Int
-> ( ControlFns input2 state2 delta2 output2, restFns2 )
-> ( State state2, restStates2 )
-> Result (List ( String, String )) output2
, stateAfter : ( Maybe a8, j )
, stateAfters : ( j, k )
, stateBefore : a7 -> c2
, stateBefores : a6 -> c1
, stateInserter :
a5
-> Int
-> Int
-> (( State argState, restArgStates ) -> tagStates)
-> ( Maybe (State argState), restMaybeArgStates )
-> ( State argState, restArgStates )
-> State tagStates
, subscriptionCollector :
a4
-> List (Sub msg)
-> ( a3 -> msg, l )
-> ( { y | subscriptions : x -> Sub a3 }, m )
-> ( x, n )
-> o
, toArgStates : a2 -> c
, updater :
a1
-> { newCmds : List (Cmd recordDelta)
, newStates : ( State state1, restStates1 ) -> recordState0
}
-> ( ControlFns input1 state1 delta output1, restFns1 )
-> ( Delta delta -> recordDelta, restDeltaSetters )
-> ( Delta delta, restDeltas )
-> ( State state1, restStates1 )
-> { newCmds : List (Cmd recordDelta)
, newStates : recordState1
}
, viewer :
a
-> Maybe (Html delta1)
-> List Flag
-> Int
-> ( ControlFns input state delta0 output, restFns )
-> ( Delta delta0 -> delta1, restSetters )
-> ( State state, restStates )
-> Maybe (Html delta1)
}

Add a tag with five arguments to a custom type.

Form internals

These are types that you will see in your form's State and Delta type signatures.

type State state

State is the form's equivalent of an Elm program's Model type. It is used to manage the form's internal state.

type Delta delta

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.

type ListDelta delta

Special Delta type used only by list controls

type End

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 ) )

Internal stuff that you can ignore

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.

type Access

An internal type used to represent whether a record field is editable, read-only, or hidden

type AdvancedControl input state delta output

A slightly more flexible version of Control

type Builder r c

An internal type used to differentiate between builders for record and custom type combinators

type alias ControlFns input state delta output =
{ index : Int
, init : ( State state, Cmd (Delta delta) )
, initWith : input -> ( State state, Cmd (Delta delta) )
, baseUpdate :
Float
-> Delta delta
-> State state
-> ( State state, Cmd (Delta delta) )
, update :
Delta delta -> State state -> ( State state, Cmd (Delta delta) )
, view :
ViewConfigStatic -> ViewConfigDynamic state -> Html (Delta delta)
, childViews :
ViewConfigStatic
-> ViewConfigDynamic state
-> List (Html (Delta delta))
, parse : State state -> Result (List ( String, String )) output
, path : Path
, emitFlags : State state -> List Flag
, collectDebouncingReceivers : State state -> List Flag
, collectErrors : State state -> List Flag -> List ( String, String )
, receiverCount : Int
, setAllIdle : State state -> State state
, label : Maybe String
, id : Maybe String
, name : Maybe String
, class : List String
, subscriptions : State state -> Sub (Delta delta)
}

Some internal stuff needed to build up record and custom type controls

type Flag

Some internal stuff needed to handle validations

type alias RecordFns input state delta output recordOutput =
{ access : Access
, field : ControlFns input state delta output
, fromInput : recordOutput -> output
}

Some internal stuff needed to build up a record control

type Status

an internal type needed to represent the validation state of a control

type alias ViewConfigStatic =
{ name : Maybe String
, id : Maybe String
, label : Maybe String
, class : List String
}

Some internal stuff needed to view controls

type alias ViewConfigDynamic state =
{ state : state
, status : Status
, flags : List Flag
, selected : Int
}

Some internal stuff needed to view controls

type alias Path =
Path

an internal type needed to track the position of a control within a tree of controls