Orchestrate commands, subscriptions, and tasks.
Execute a procedure that cannot fail.
Note: The first argument tags a Procedure.Program.Msg as a Msg in your application.
The second argument tags the value produced by the Procedure as a Msg in your application.
Execute a procedure that may fail.
Note: The first argument tags a Procedure.Program.Msg as a Msg in your application.
The second argument tags the result of the Procedure as a Msg in your application.
Generate a procedure that simply provides a value.
Procedure.provide "Hello!"
|> Procedure.run ProcedureTagger StringTaggerThis will result in StringTagger "Hello".
Generate a procedure that gets the value produced by executing some Cmd.
For example, if you wanted to have the user select a file and then convert that to a string, you could do the following:
Procedure.fetch (File.Select.file ["application/zip"])
|> Procedure.andThen (\file ->
File.toString file
|> Procedure.fromTask
)
|> Procedure.run ProcedureTagger StringTaggerNote that only some commands produce a value directly. To execute those commands
that do not produce a value, use do.
Generate a procedure that gets the result produced by executing some Cmd.
For example, if you wanted to make an Http request and then map the response, you could do the following:
Procedure.fetchResult (\tagger ->
Http.get
{ url = "http://fun.com/fun.html"
, expect = Http.expectString tagger
}
)
|> Procedure.map (\words ->
"Fun stuff: " ++ words
)
|> Procedure.catch (\error ->
Procedure.provide "No Response"
)
|> Procedure.run ProcedureTagger StringTaggerIf the Http request fails, then the result will be: No response.
Generate a procedure that collects the results of a list of procedures.
Procedure.collect
[ Procedure.provide "One"
, Procedure.provide "Two"
, Procedure.provide "Three"
]
|> Procedure.run ProcedureTagger ListStringTaggerThen the result would be ListStringTagger [ "One", "Two", "Three" ].
Generate a procedure that runs a task.
For example, if you wanted to have the user select a file and then convert that to a string, you could do the following:
Procedure.fetch (File.Select.file ["application/zip"])
|> Procedure.andThen (\file ->
File.toString file
|> Procedure.fromTask
)
|> Procedure.run ProcedureTagger StringTaggerIf the task fails, the procedure will break at this point, just as
if Procedure.break had been used.
Generate a procedure that breaks out of the current procedure.
You can use this to stop a procedure early:
Procedure.fetch (File.Select.file ["text/plain"])
|> Procedure.andThen (\file ->
File.toString file
|> Procedure.fromTask
)
|> Procedure.andThen (\text ->
if String.length text > 100 then
Procedure.break "File is too long!"
else
Procedure.provide text
)
|> Procedure.map (\text -> doSomethingWithTheText text)
|> Procedure.try ProcedureTagger StringResultTaggerwhere StringResultTagger tags a Result String String. If the break is triggered,
then the result would be Err "File is too long!".
Generate a procedure that executes a Cmd that does not produce any value directly.
Use do to execute port functions that generate Cmd values.
Procedure.do myFunPortCommand
|> Procedure.map (\_ -> "We did it!")
|> Procedure.run ProcedureTagger StringTaggerIf you want to send a port command and expect a response later via some subscription, use
a Channel.
Generate a new procedure based on the result of the previous procedure.
Procedure.provide "An awesome value"
|> Procedure.andThen (\data ->
Procedure.provide <| data ++ "!!!"
)
|> Procedure.run ProcedureTagger StringTaggerThen the result would be StringTagger "An awesome value!!!".
Generate a new procedure when some previous procedure results in an error, usually
do to processing a break procedure.
For example, you could check the result of some data
and then break to skip the next steps until you reach a catch step.
Procedure.fetch someCommand
|> Procedure.andThen (\data ->
if data.message == "Success" then
Procedure.provide data
else
Procedure.break data.message
)
|> Procedure.andThen (\data ->
Channel.send (somePortCommand data)
|> Channel.receive somePortSubscription
|> Channel.await
)
|> Procedure.catch (\errorData ->
Procedure.provide "Some default message"
)
|> Procedure.map (\data -> data ++ "!")
|> Procedure.run ProcedureTagger StringTaggerIf the data fetched via someCommand is deemed not successful, then
the next steps will be skipped and the result of this procedure will
be StringTagger "Some default message!".
Generate a procedure that transforms the value of the previous procedure.
Procedure.collect
[ Procedure.provide "One"
, Procedure.provide "Two"
, Procedure.provide "Three"
]
|> Procedure.map (String.join ", ")
|> Procedure.run ProcedureTagger StringTaggerThen the result would be StringTagger "One, Two, Three".
Generate a procedure that provides a new value based on the values of two other procedures
Procedure.map2
(\a b -> a ++ " AND " ++ b)
(Procedure.provide "One")
(Procedure.provide "Two")
|> Procedure.run ProcedureTagger StringTaggerThen the result would be `StringTagger "One AND Two"
Generate a procedure that provides a new value based on the values of three other procedures.
Generate a procedure that transforms the error value of a previous procedure.
Procedure.provide "Start"
|> Procedure.andThen (\_ -> Procedure.break "Oops")
|> Procedure.mapError (\err -> err ++ "???")
|> Procedure.try ProcedureTagger ResultTaggerThen the result would be Err "Oops???".
Note: Error values can be set explicitly by using break.
Represents some sequence of commands, subscriptions, or tasks that ultimately results in some value.