Module Relude_AsyncData
Relude.AsyncData
contains an variant type t('a)
for representing the different states in which a value can be during an asynchronous data load. Because the type only has a single type parameter 'a
, it cannot represent failures by default, but you can choose to use any type for 'a
, including option('b)
(for data that may or may not load), result('b, 'e)
(for data that can fail to load), etc.
If you need to represent an error condition along with the success condition, see Relude_AsyncResult
.
The variant type has the following constructors:
Init
Loading
Reloading('a)
Complete('a)
This type is similar to the Elm RemoteData type, with a few key differences:
AsyncData
does not inherently have the concept of failure (again, seeRelude_AsyncResult
if that's something you want).AsyncData
has aReloading('a)
state which can be used to indicate that data is being refreshed/reloaded/saved while retaining a current (or previous) value. E.g. if you have loaded some data, and need to reload it but want to keep the current value around for display purposes, you might use theReloading('a)
state rather than theLoading
state which does not carry any data.
AsyncData
has instances of various typeclasses like Functor
, Applicative
, Monad
etc. which unlock the ability to compose and combine AsyncData
values using functions like map2
-map5
, flatMap
, traverse
, etc.
For example, if you have multiple pieces of data that are being loaded asynchronously, you can combine the results of several AsyncData
values into a single tupled AsyncData
value using map2
, map3
, etc. or any of the other combinators.
type t('a)
=
;|
Init
|
Loading
|
Reloading('a)
|
Complete('a)
AsyncData represents the state of data that is being loaded asynchronously. While Promise and IO represent the effect of loading that data,
AsyncData
represents what that data looks like at one particular snapshot in time. This is particularly useful when storing application state (e.g. in a React component).By default, this type does not represent failures. If you want to represent the possibility for an async value to fail, you can use a
result
in the'a
type (or seeAsyncResult
, which does this for you).The reason for this is that not all async data loading mechanisms will necessarily fail.
The other interesting bit is that
Reloading
can be used if you already have data, but you need to reload the data to get a new value.
let init: t('a);
Constructs an Init value
let loading: t('a);
Constructs a Loading value
let reloading: 'a => t('a);
Constructs a Reloading value containing the given value
let complete: 'a => t('a);
Constructs a Reloading value containing the given value
let isInit: a. t('a) => bool;
Checks if this AsyncData value is Init
let isLoading: a. t('a) => bool;
Checks if this AsyncData value is Loading
let isReloading: a. t('a) => bool;
Checks if this AsyncData value is Reloading with any value
let isComplete: a. t('a) => bool;
Checks if this AsyncData value is Complete with any value
let isBusy: a. t('a) => bool;
Checks if this AsyncData value is working (Loading or Reloading)
let isIdle: a. t('a) => bool;
Checks if this AsyncData value is not working (Init or Complete)
let isEmpty: a. t('a) => bool;
Checks if this AsyncData value is Init or Loading
let isNotEmpty: a. t('a) => bool;
Checks if this AsyncData value is Reloading or Complete
let toBusy: a. t('a) => t('a);
Creates a new
AsyncData
by transitioning the givenAsyncData
into a busy state (Loading
orReloading
), and carrying over the internal data if available.
let toIdle: a. t('a) => t('a);
Creates a new
AsyncData
by transitioning the givenAsyncData
into an idle state (Init
orComplete
), and carrying over the internal data if available.
let getValue: a. t('a) => option('a);
Get a value of type
'a
, using theComplete
value if the AsyncData is complete, or the last known complete value inReloading
.
let getReloading: a. t('a) => option('a);
Get
Some
value of type'a
only from theReloading
state, andNone
in all other cases, includingComplete
let getComplete: a. t('a) => option('a);
Get
Some
value of type'a
only from theComplete
state, andNone
in all other cases, includingReloading
.
let fold: a b. 'b => 'b => ('a => 'b) => ('a => 'b) => t('a) => 'b;
Fold the
AsyncData
into a new type by providing a strict value or function to handle each case.
let foldLazy: a b. (unit => 'b) => (unit => 'b) => ('a => 'b) => ('a => 'b) => t('a) => 'b;
Fold the
AsyncData
into a new value by providing a function to handle each case.
let foldByValue: a b. 'b => ('a => 'b) => t('a) => 'b;
Fold the
AsyncData
into a new value by providing a strict value to use when there is no data, or function to handle when there is data.
let foldByValueLazy: a b. (unit => 'b) => ('a => 'b) => t('a) => 'b;
Fold the
AsyncData
into a new value by providing a lazy value to use when there is no data, or function to handle when there is data.
let map: a b. ('a => 'b) => t('a) => t('b);
Maps a pure function over the value contained by Reloading or Complete
include { ... };
module BsFunctorExtensions: { ... };
let tap: a. (unit => unit) => (unit => unit) => ('a => unit) => ('a => unit) => t('a) => t('a);
Applies a side effect function for each case of the variant (Init, Loading, Reloading, Complete)
let tapInit: a. (unit => unit) => t('a) => t('a);
Applies a side effect function if the value is Init
let tapLoading: a. (unit => unit) => t('a) => t('a);
Applies a side effect function if the value is Loading
let tapReloading: a. ('a => unit) => t('a) => t('a);
Applies a side effect function if the value is Reloading
let tapComplete: a. ('a => unit) => t('a) => t('a);
Applies a side effect function if the value is Complete
let tapEmpty: a. (unit => unit) => t('a) => t('a);
Applies a side effect function if the value is Init or Loading
let tapNotEmpty: a. ('a => unit) => t('a) => t('a);
Applies a side effect function if the value is Reloading or Complete
let tapByValue: a. (unit => unit) => ('a => unit) => t('a) => t('a);
Applies a side effect function for the empty case and the not-empty case
let apply: a b. t(('a => 'b)) => t('a) => t('b);
Applies a wrapped function to the value contained by Reloading or Complete
include { ... };
module BsApplyExtensions: { ... };
let applyFirst: Apply.t('a) => Apply.t('b) => Apply.t('a);
let applySecond: Apply.t('a) => Apply.t('b) => Apply.t('b);
let map2: ('a => 'b => 'c) => Apply.t('a) => Apply.t('b) => Apply.t('c);
let map3: ('a => 'b => 'c => 'd) => Apply.t('a) => Apply.t('b) => Apply.t('c) => Apply.t('d);
let map4: ('a => 'b => 'c => 'd => 'e) => Apply.t('a) => Apply.t('b) => Apply.t('c) => Apply.t('d) => Apply.t('e);
let map5: ('a => 'b => 'c => 'd => 'e => 'f) => Apply.t('a) => Apply.t('b) => Apply.t('c) => Apply.t('d) => Apply.t('e) => Apply.t('f);
let tuple2: Apply.t('a) => Apply.t('b) => Apply.t(('a, 'b));
let tuple3: Apply.t('a) => Apply.t('b) => Apply.t('c) => Apply.t(('a, 'b, 'c));
let tuple4: Apply.t('a) => Apply.t('b) => Apply.t('c) => Apply.t('d) => Apply.t(('a, 'b, 'c, 'd));
let tuple5: Apply.t('a) => Apply.t('b) => Apply.t('c) => Apply.t('d) => Apply.t('e) => Apply.t(('a, 'b, 'c, 'd, 'e));
let mapTuple2: ('a => 'b => 'c) => (Apply.t('a), Apply.t('b)) => Apply.t('c);
let mapTuple3: ('a => 'b => 'c => 'd) => (Apply.t('a), Apply.t('b), Apply.t('c)) => Apply.t('d);
let mapTuple4: ('a => 'b => 'c => 'd => 'e) => (Apply.t('a), Apply.t('b), Apply.t('c), Apply.t('d)) => Apply.t('e);
let mapTuple5: ('a => 'b => 'c => 'd => 'e => 'f) => (Apply.t('a), Apply.t('b), Apply.t('c), Apply.t('d), Apply.t('e)) => Apply.t('f);
let pure: a. 'a => t('a);
Lifts a pure value into the context of an AsyncData, in the Complete state
module Applicative: BsBastet.Interface.APPLICATIVE with type Applicative.t('a) = t('a);
include { ... };
module BsApplicativeExtensions: { ... };
let liftA1: ('a => 'b) => Applicative.t('a) => Applicative.t('b);
let when_: bool => Applicative.t(unit) => Applicative.t(unit);
let unless: bool => Applicative.t(unit) => Applicative.t(unit);
let all: list(Applicative.t('a)) => Applicative.t(list('a));
let bind: a b. t('a) => ('a => t('b)) => t('b);
Applies a monadic function to the value contained by Reloading or Complete
include { ... };
module BsMonadExtensions: { ... };
let flatMap: ('a => Monad.t('b)) => Monad.t('a) => Monad.t('b);
let flatten: Monad.t(Monad.t('a)) => Monad.t('a);
let composeKleisli: ('a => Monad.t('b)) => ('b => Monad.t('c)) => 'a => Monad.t('c);
let flipComposeKleisli: ('b => Monad.t('c)) => ('a => Monad.t('b)) => 'a => Monad.t('c);
let liftM1: ('a => 'b) => Monad.t('a) => Monad.t('b);
let when_: Monad.t(bool) => Monad.t(unit) => Monad.t(unit);
let unless: Monad.t(bool) => Monad.t(unit) => Monad.t(unit);
let alt: a. t('a) => t('a) => t('a);
alt for AsyncData tries to find the most advanced state between two AsyncData values in terms of completeness.
let eqBy: a. ('a => 'a => bool) => t('a) => t('a) => bool;
Indicates if two AsyncData values are in the same state, and that the contained values are equal.
module Eq: (E: BsBastet.Interface.EQ) => BsBastet.Interface.EQ;
let showBy: a. ('a => string) => t('a) => string;
Converts an AsyncData value to a string, using the given function to convert the contained value to a string.
module Show: (S: BsBastet.Interface.SHOW) => BsBastet.Interface.SHOW;
module Infix: { ... };