Run Update
s sequentially.
import Update exposing (Update)
import Update.Sequence as Sequence exposing (Sequence)
type Value
= Start
| ClickNext
| SubmitText
| NeverUsed
type Msg
= SequenceMsg (Sequence.Msg Value)
type alias Model =
{ sequence : Sequence.Model
, notice : String
, text : String
}
update : Msg -> Update Model Msg
update (SequenceMsg msg) =
Sequence.run
{ get = .sequence
, set = \seq model -> { model | sequence = seq }
}
msg
[ Sequence.on Start
[ setNotice "Tutorial has started!"
]
, Sequence.on ClickNext
[ setNotice "The first next button is clicked."
]
, Sequence.on ClickNext
[ setNotice "The second next button is clicked."
]
, \v -> Sequence.when (v == SubmitText) <| Sequence.with <| \{ text } ->
if text == "" then
Sequence.waitAgain <|
setNotice "Invalid text. Retry!"
else
Sequence.succeed <|
setNotice <| text ++ " is submitted."
, Sequence.on ClickNext
[ setNotice "The last next button is clicked."
]
]
-- Helper functions
setNotice : String -> Update Model msg
setNotice notice = Update.modify <| \model -> { model | notice = notice }
-- Test the update function
model0 : Model
model0 =
{ sequence = Sequence.initModel
, notice = "initial"
, text = "initial text"
}
model1 : Model
model1 =
Update.run
(update <| SequenceMsg <| Sequence.resolve Start)
model0
|> Tuple.first
model1.notice
--> "Tutorial has started!"
model2 : Model
model2 =
Update.run
(update <| SequenceMsg <| Sequence.resolve ClickNext)
model1
|> Tuple.first
model2.notice
--> "The first next button is clicked."
-- Notice that here we provide the very same event as previous.
model3 : Model
model3 =
Update.run
(update <| SequenceMsg <| Sequence.resolve ClickNext)
model2
|> Tuple.first
model3.notice
--> "The second next button is clicked."
-- The result shows that we get the second notice rather than the first one.
model4 : Model
model4 =
Update.run
(update <| SequenceMsg <| Sequence.resolve SubmitText)
{ model3 | text = "" }
|> Tuple.first
model4.notice
--> "Invalid text. Retry!"
-- Notice that here we provides the resulting `model4`, but not the previous `model3` again.
model5 : Model
model5 =
Update.run
(update <| SequenceMsg <| Sequence.resolve SubmitText)
{ model4 | text = "valid text" }
|> Tuple.first
model5.notice
--> "valid text is submitted."
-- The result shows that we can retry the current `Sequence`.
model6 : Model
model6 =
Update.run
(update <| SequenceMsg <| Sequence.resolve <| ClickNext)
model5
|> Tuple.first
model6.notice
--> "The last next button is clicked."
run : Update.Lifter.Lifter model Model -> Msg value -> List (value -> Sequence model msg) -> Update model msg
initModel : Model
resolve : value -> Msg value
call : v -> Update model (Msg v)
succeed : Update model msg -> Sequence model msg
Construct a Sequence
always succeeds with given Update
s.
waitAgain : Update model msg -> Sequence model msg
Construct a Sequence
always wait again after evaluating given Update
s.
with : (model -> Sequence model msg) -> Sequence model msg
when : Basics.Bool -> Sequence model msg -> Sequence model msg
Succeed Sequence
only if it meets the condition.
Otherwise, it waitAgain
with Update.none
.
unless : Basics.Bool -> Sequence model msg -> Sequence model msg
Succeed Sequence
unless it meets the condition.
Otherwise, it waitAgain
with Update.none
.
on : value -> List (Update model msg) -> value -> Sequence model msg
Generate a Sequence that succeeds only under certain value.
It succeeds with Update
s only if the fired message value is equals to its first argument, otherwise it waitAgain
with Update.none
.
onAnyOf : List value -> List (Update model msg) -> value -> Sequence model msg
Generate a Sequence that succeeds only under certain values.
It succeeds with Update
s only if the fired message value is one of its first argument, otherwise it waitAgain
with Update.none
.
anyOf : List (value -> Sequence model msg) -> value -> Sequence model msg
Evaluate Sequence
s from top to bottom.
Once a Sequence
succeeds, it does not evaluate subsequent Sequence
s.
Sequence.anyOf
[ Sequence.on ClickOk
[ setNotice "Ok"
]
, Sequence.on ClickNg
[ setNotice "Ng"
]
]
onJust : List (a -> Update model msg) -> Maybe a -> Sequence model msg
Generate a Sequence that succeeds only on Just
values.
It succeeds with Update
s only if the value is Just
, otherwise it waitAgain
with Update.none
.
onNothing : List (Update model msg) -> Maybe a -> Sequence model msg
Generate a Sequence that succeeds only on Nothing
values.
It succeeds with Update
s only if the value is Nothing
, otherwise it waitAgain
with Update.none
.
onOk : List (a -> Update model msg) -> Result err a -> Sequence model msg
Generate a Sequence that succeeds only on Ok
values.
It succeeds with Update
s only if the value is Ok
, otherwise it waitAgain
with Update.none
.
onErr : List (err -> Update model msg) -> Result err a -> Sequence model msg
Generate a Sequence that succeeds only on Err
values.
It succeeds with Update
s only if the value is Err
, otherwise it waitAgain
with Update.none
.