The Requested type and associated functions.
The Requested type is an opinionated paradigm for managing asynchronous, fallible operations, particularly those which can happen several times.
The README gives a good overview. This module houses the Requested type itself and the functions you probably need to use it.
The Requested type.
A Requested t e a
has at least one of:
"At least one" indicates that some previous results are retained:
The type t represents a "tracker" which is used to identify requests. You are required to provide a comparison function to order trackers. We keep the tracker for each response so that we can handle out-of-order responses.
The constructors are:
Succeeded
: The latest response was successful. We also keep the
tracker that produced this successful response, which lets us
identify newer responses (should we transition to Failed
or
Outstanding
). Additionally, you may find that you want to use
the tracker to identify the current state in some way.
Failed
: The latest response was a failure. We also keep the last
success. If successes come in that are newer than that success, we
will update it. Failures should not come in that are newer than
the last failure because if there were newer requests, we should
be in Outstanding
.
Outstanding
: A request has been issued to which we have not
received the response yet. That request should always be the
newest request made for this Requested
. If we are not in this
state, then it should be impossible to receive a response later
than what we have.
Responses for other requests will be used, if necessary, to update the previous failure and previous success states, but we will remain "waiting" until we get the response corresponding to our current request.
fromTracker : t -> Requested t e a
Construct a Requested from an initial request.
This is the most common way of creating a Requested.
fromSuccess : t -> a -> Requested t e a
Utility function to construct a Requested when you already have the data it would fetch.
fromFailure : t -> e -> Requested t e a
Utility function to construct a Requested when you already have a failure.
This lets you make lemonade, even when life gives you lemons.
This function is provided for completeness, but generally isn't that useful.
mapSuccess : (a1 -> a2) -> Requested t e a1 -> Requested t e a2
Transform the success values in the Requested, if any.
mapFailure : (e1 -> e2) -> Requested t e1 a -> Requested t e2 a
Transform the failure values in the Requested, if any.
mapTracker : (t1 -> t2) -> Requested t1 e a -> Requested t2 e a
Transform the trackers in the Requested.
isOutstanding : Requested t e a -> Basics.Bool
Check if a Requested is waiting for a request to complete.
This might be useful when choosing to display a "Loading..." state in your view.
withResponse : (t -> t -> Basics.Order) -> t -> Result e a -> Requested t e a -> Requested t e a
Update the Requested with data that came in from the request given by the tracker.
If this Requested is waiting for a request, and this request matches the given tracker, then produce a new non-waiting Requested.
If this Requested is waiting for a different request, the provided data probably represents a response from an older request. Update the Requested to use this data (if necessary), but remain in a "waiting" state.
Otherwise, the Requested is not waiting for a request. Because requests are ordered, and we aren't in Outstanding, the response must be older than what we have, so we will remain in whatever state we are in (Failed or Succeeded). If we are in Failed, it's possible that this is a newer success than our "last success", so update that.
N.B. This function is pretty strict about responses being ordered and
being in Outstanding if you have made a new request. We don't check if
a response is newer "just in case" or anything like that because that
would hide bugs. Instead, if your ordering function is screwed up
somehow, or you forgot to call refresh
, some updates will be
silently ignored.
FIXME: some use cases might not want to incorporate data from old requests. Provide another function for them.
refresh : t -> Requested t e a -> Requested t e a
Update this Requested to reflect that we are making a new request.
getSuccess : Requested t e a -> Maybe ( t, a )
Get the previous success from the Requested, if any.
This is a utility function which may be useful in writing views.
getFailure : Requested t e a -> Maybe ( t, e )
Get the previous failure from the Requested, if any.
This is a utility function which may be useful in writing views.
fromResult : t -> Result e a -> Requested t e a
Utility function to create a Requested given a Result.
This is provided for completeness.