Marjoram  0.01
Library for Functional Programming in C++
Either

Either Monad, supporting constants and functions. More...

Classes

class  ma::EitherIterator< A, B >
 Right-biased iterator. More...
 
class  ma::ConstEitherIterator< A, B >
 Right-biased const iterator. More...
 
class  ma::Maybe< A >
 Maybe monad. More...
 
class  ma::Either< A, B >
 Either monad. More...
 

Detailed Description

Either Monad, supporting constants and functions.

An instance of Either<A,B> contains either an A or a B. Unlike std::variant both A and B may be the same type.

Example

Given a function that returns either a fully fledged Widget or a descriptive Error message.

class Widget;
class BetterWidget;
BetterWidget refine(Widget& w);
Either<std::string, Widget> requestWidget(double length, int numberOfBells);

Then client code can treat the above return value uniformly:

Either<std::string, Widget> emw = requestWidget(14.2, 3);
Either<std::string, BetterWidget> morphed =
emw.map([](Widget& w) { return refine(w); });

Class Documentation

◆ ma::EitherIterator

class ma::EitherIterator

template<typename A, typename B>
class ma::EitherIterator< A, B >

Right-biased iterator.

Allows mutable access to the right value of an Either.

Example:

Either<A, B> e;
[...]
for (B& b: e) {
// use `b`
}
See also
ConstEitherIterator

Public Types

using iterator_category = std::input_iterator_tag
 
using difference_type = size_t
 
using value_type = B
 
using reference = B &
 
using pointer = B *
 

Public Member Functions

 EitherIterator (Either< A, B > &Mb, bool start)
 
bool operator!= (const EitherIterator< A, B > &other)
 
reference operator* ()
 
pointer operator-> ()
 
EitherIteratoroperator++ ()
 
EitherIteratoroperator++ (int)
 

◆ ma::ConstEitherIterator

class ma::ConstEitherIterator

template<typename A, typename B>
class ma::ConstEitherIterator< A, B >

Right-biased const iterator.

See also
EitherIterator

Public Types

using iterator_category = std::input_iterator_tag
 
using difference_type = size_t
 
using value_type = const B
 
using reference = const B &
 
using pointer = const B *
 

Public Member Functions

 ConstEitherIterator (const Either< A, B > &Mb, bool start)
 
bool operator!= (const ConstEitherIterator< A, B > &other)
 
reference operator* ()
 
pointer operator-> ()
 
ConstEitherIteratoroperator++ ()
 
ConstEitherIteratoroperator++ (int)
 

◆ ma::Maybe

class ma::Maybe

template<typename A>
class ma::Maybe< A >

Maybe monad.

May contain a value or Nothing.

Throughout the documentation, if an object of type Maybe<A> contains a value, this value is denoted by a.

Type requirements: A must be a value type

Public Types

using value_type = A
 

Public Member Functions

 Maybe (Nothing_t)
 New empty object (containing Nothing).
 
 Maybe ()
 New empty object (containing Nothing).
 
 Maybe (const A &a)
 Copy a into new Maybe instance.
 
 Maybe (A &&a)
 Move a into new Maybe instance.
 
 Maybe (const Maybe< A > &Ma)=default
 Copy Maybe instance.
 
 Maybe (Maybe< A > &&Ma)=default
 Move Maybe instance.
 
Maybe< A > & operator= (const Maybe< A > &Ma)=default
 
Maybe< A > & operator= (Maybe< A > &&Ma)=default
 
template<typename F >
auto flatMap (F f) const -> std::result_of_t< F(A)>
 Returns result of f(a) wrapped in a Maybe if this holds a value, otherwise returns Nothing. More...
 
template<typename F >
auto flatMap (F f) -> std::result_of_t< F(A)>
 Returns result of f(a) if this holds a value, otherwise returns Nothing. More...
 
template<typename F >
auto map (F f) const -> Maybe< std::result_of_t< F(A)>>
 Returns maybe containing result of f(a) if this holds a value, otherwise returns Nothing. More...
 
template<typename F >
auto map (F f) -> Maybe< std::result_of_t< F(A)>>
 Returns maybe containing result of f(a) if this holds a value, otherwise returns Nothing. More...
 
template<typename B >
bool contains (const B &b) const
 
template<class Left >
Either< Left, A > toRight (const Left &left) const
 
template<class Right >
Either< A, Right > toLeft (const Right &right) const
 
bool isJust () const
 Checks whether this instance contains a value. More...
 
bool isNothing () const
 Checks whether this instance does not contain a value. More...
 
const A & get () const
 Obtains contained value. More...
 
A & get ()
 Obtains contained value. More...
 
const A & getOrElse (const A &dflt) const
 If this object contains a value, returns it. More...
 
template<class Predicate >
bool exists (Predicate pred) const
 Return result of applying predicate to stored value if there is one, false otherwise. More...
 
MaybeIterator< A > begin ()
 
ConstMaybeIterator< A > begin () const
 
ConstMaybeIterator< A > cbegin () const
 
MaybeIterator< A > end ()
 
ConstMaybeIterator< A > end () const
 
ConstMaybeIterator< A > cend () const
 

Member Function Documentation

◆ contains()

template<typename A>
template<typename B >
bool ma::Maybe< A >::contains ( const B &  b) const
inline
Returns
true iff this maybe instance contains a value that compares true to b.

◆ exists()

template<typename A>
template<class Predicate >
bool ma::Maybe< A >::exists ( Predicate  pred) const
inline

Return result of applying predicate to stored value if there is one, false otherwise.

Parameters
predCallable with const A&, returns bool convertible.

◆ flatMap() [1/2]

template<typename A>
template<typename F >
auto ma::Maybe< A >::flatMap ( f) const -> std::result_of_t<F(A)>
inline

Returns result of f(a) wrapped in a Maybe if this holds a value, otherwise returns Nothing.

Parameters
fFunction object.

Type requirement:

  • F::operator() when called with const A& argument has return type Maybe<B>, where B is non void.
Returns
Maybe<B> containing the result of f(a) or Nothing.

◆ flatMap() [2/2]

template<typename A>
template<typename F >
auto ma::Maybe< A >::flatMap ( f) -> std::result_of_t<F(A)>
inline

Returns result of f(a) if this holds a value, otherwise returns Nothing.

Parameters
fFunction object.

Type requirement:

  • F::operator() when called with A&& argument has return type Maybe<B>, where B is non void
Returns
Maybe<B> containing the result of f(a) or Nothing.

◆ get() [1/2]

template<typename A>
const A& ma::Maybe< A >::get ( ) const
inline

Obtains contained value.

Undefined behavior if this Maybe does not contain a value.

Returns
const reference to contained value.

◆ get() [2/2]

template<typename A>
A& ma::Maybe< A >::get ( )
inline

Obtains contained value.

Undefined behavior if this Maybe does not contain a value.

Returns
reference to contained value.

◆ getOrElse()

template<typename A>
const A& ma::Maybe< A >::getOrElse ( const A &  dflt) const
inline

If this object contains a value, returns it.

Otherwise returns dflt.

Returns
reference to contained value.

◆ isJust()

template<typename A>
bool ma::Maybe< A >::isJust ( ) const
inline

Checks whether this instance contains a value.

Returns
true if this instance contains a value.

◆ isNothing()

template<typename A>
bool ma::Maybe< A >::isNothing ( ) const
inline

Checks whether this instance does not contain a value.

Returns
true if this instance does not contain a value.

◆ map() [1/2]

template<typename A>
template<typename F >
auto ma::Maybe< A >::map ( f) const -> Maybe<std::result_of_t<F(A)>>
inline

Returns maybe containing result of f(a) if this holds a value, otherwise returns Nothing.

Parameters
fFunction object.

Type requirement:

  • F::operator() when called with const A& argument has non-void return type B.
Returns
Maybe<B> containing the result of f(a) or Nothing.

◆ map() [2/2]

template<typename A>
template<typename F >
auto ma::Maybe< A >::map ( f) -> Maybe<std::result_of_t<F(A)>>
inline

Returns maybe containing result of f(a) if this holds a value, otherwise returns Nothing.

Parameters
fFunction object.

Type requirement:

  • F::operator() when called with argument of type A&& has non-void return type B.
Returns
Maybe<B> containing the result of f(a) or Nothing.

◆ toLeft()

template<typename A>
template<class Right >
Either<A, Right> ma::Maybe< A >::toLeft ( const Right &  right) const
inline
Returns
ma::Either containing either the stored value or the argument.

◆ toRight()

template<typename A>
template<class Left >
Either<Left, A> ma::Maybe< A >::toRight ( const Left &  left) const
inline
Returns
ma::Either containing either the stored value or the argument.

◆ ma::Either

class ma::Either

template<typename A, typename B>
class ma::Either< A, B >

Either monad.

Disjoint union of two types.

Note that a Either is a monad if one of the type arguments are fixed, we chose the left one to remain fixed under flatMap, i.e.,

Either<A,>B::flatMap(F) -> Either<A, C>

Where C is the result of F(A).

Terminology: If an Either<A, B> contains an A value, we say it has a left value, similarly for B and right.

Public Types

using value_type = B
 
using left_type = A
 
using right_type = B
 

Public Member Functions

template<typename... Args, typename = typename std::enable_if< std::is_constructible<A, Args...>::value ^ std::is_constructible<B, Args...>::value>::type>
 Either (Args &&... args)
 Convenience constructor that infers the Either's side (right or left). More...
 
template<typename... Args>
 Either (LeftSide, Args &&... args)
 Construct left Either<A, B> containing an A. More...
 
template<typename... Args>
 Either (RightSide, Args &&... args)
 Construct right Either<A, B> containing an B. More...
 
bool isLeft () const
 Checks whether an A is stored. More...
 
bool isRight () const
 Checks whether a B is stored. More...
 
template<typename Fa , typename Fb >
auto fold (Fa fa, Fb fb) const -> std::result_of_t< Fa(A)>
 Reduces Either<A, B> to single value via two function objects. More...
 
template<typename Fa , typename Fb >
auto fold (Fa fa, Fb fb) -> std::result_of_t< Fa(A)>
 Reduces Either<A, B> to single value via two function objects. More...
 
template<typename Fb >
auto flatMap (Fb fb) const -> std::result_of_t< Fb(B)>
 Applies supplied function to stored B value if one is available. More...
 
template<typename Fb >
auto flatMap (Fb fb) -> std::result_of_t< Fb(B)>
 Applies supplied function to stored B value if one is available. More...
 
template<typename Fb >
auto map (Fb fb) -> Either< A, std::result_of_t< Fb(B)>>
 Applies supplied function to stored B value if one is available and wraps the result in Either. More...
 
template<typename Fb >
auto map (Fb fb) const -> Either< A, std::result_of_t< Fb(B)>>
 Applies supplied function to stored B value if one is available and wraps result in Either. More...
 
template<class Predicate >
bool exists (Predicate pred) const
 If right sided either, return result of applying predicate on right. More...
 
const B & getOrElse (const B &dflt)
 Returns contained right value or given default value.
 
Either< B, A > mirror () const
 Swaps left and right, preserving the stored value. More...
 
Maybe< B > toMaybe () const
 If a B is contained, returns Just(B). More...
 
template<typename C >
bool contains (const C &c)
 
template<typename Fa >
recover (Fa fa) const
 
template<class Dummy = A>
auto merge () const -> typename std::enable_if< std::is_same< A, B >::value, const Dummy &>::type
 If both left and right have the same type, allows merging to common type. More...
 
template<class BB = B>
auto rightJoin () const -> typename std::enable_if< std::is_same< Either< typename BB::left_type, typename BB::right_type >, right_type >::value &&std::is_same< left_type, typename BB::left_type >::value, Either< left_type, typename BB::right_type >>::type
 Joins instance of Either through right. More...
 
template<class AA = A>
auto leftJoin () const -> typename std::enable_if< std::is_same< Either< typename AA::left_type, typename AA::right_type >, left_type >::value &&std::is_same< right_type, typename AA::right_type >::value, Either< typename AA::left_type, right_type >>::type
 Joins instance of Either through left. More...
 
EitherIterator< A, B > begin ()
 
ConstEitherIterator< A, B > begin () const
 
ConstEitherIterator< A, B > cbegin () const
 
EitherIterator< A, B > end ()
 
ConstEitherIterator< A, B > end () const
 
ConstEitherIterator< A, B > cend () const
 

Private Member Functions

B & asRight ()
 Returns stored B value. More...
 
const B & asRight () const
 Returns stored B value. More...
 
A & asLeft ()
 Returns stored A value. More...
 
const A & asLeft () const
 Returns stored A value. More...
 

Private Attributes

EitherSide side
 Indicates whether this contains an A or a B.
 

Constructor & Destructor Documentation

◆ Either() [1/3]

template<typename A, typename B>
template<typename... Args, typename = typename std::enable_if< std::is_constructible<A, Args...>::value ^ std::is_constructible<B, Args...>::value>::type>
ma::Either< A, B >::Either ( Args &&...  args)
inline

Convenience constructor that infers the Either's side (right or left).

Disabled if both A and B can be constructed from the input arguments.

◆ Either() [2/3]

template<typename A, typename B>
template<typename... Args>
ma::Either< A, B >::Either ( LeftSide  ,
Args &&...  args 
)
inline

Construct left Either<A, B> containing an A.

Note that LeftSide is just a tag, a const static instance is declared as ma::Left for convenience. Example:

auto e = Either<double, int>(ma::Left, 5);

Constructs a left sided Either containing a double (although a int could have bound to 5 as well).

◆ Either() [3/3]

template<typename A, typename B>
template<typename... Args>
ma::Either< A, B >::Either ( RightSide  ,
Args &&...  args 
)
inline

Construct right Either<A, B> containing an B.

Note that RightSide is just a tag, a const static instance is declared as ma::Right for convenience.

Member Function Documentation

◆ contains()

template<typename A, typename B>
template<typename C >
bool ma::Either< A, B >::contains ( const C &  c)
inline
Returns
True if contains a B value that compares equal to argument b.

◆ exists()

template<typename A, typename B>
template<class Predicate >
bool ma::Either< A, B >::exists ( Predicate  pred) const
inline

If right sided either, return result of applying predicate on right.

Otherwise return false.

Parameters
predFunction object, when called with argument of type A must return bool convertible.

◆ flatMap() [1/2]

template<typename A, typename B>
template<typename Fb >
auto ma::Either< A, B >::flatMap ( Fb  fb) const -> std::result_of_t<Fb(B)>
inline

Applies supplied function to stored B value if one is available.

Parameters
fbFunction object. F::operator() when called with const B& has return type Either<A, C>.
Returns
If this object contains a B value, the result of fb(b) is stored in the returned either. Otherwise, the pre-existing A value is copied into the return value.

◆ flatMap() [2/2]

template<typename A, typename B>
template<typename Fb >
auto ma::Either< A, B >::flatMap ( Fb  fb) -> std::result_of_t<Fb(B)>
inline

Applies supplied function to stored B value if one is available.

Parameters
fbFunction object. F::operator() when called with B&& has return type Either<A, C>.
Returns
If this object contains a B value, the result of fb(b) is stored in the returned either. Otherwise, the pre-existing A value is copied into the return value.

◆ fold() [1/2]

template<typename A, typename B>
template<typename Fa , typename Fb >
auto ma::Either< A, B >::fold ( Fa  fa,
Fb  fb 
) const -> std::result_of_t<Fa(A)>
inline

Reduces Either<A, B> to single value via two function objects.

Parameters
faFunction object that can be applied to an A.
fbFunction object that can be applied to a B.
Returns
Result of either fa(a) or fb(b) depending on which kind of value is contained.

Note that both fa and fb must have the same return type when applied to their respective arguments.

◆ fold() [2/2]

template<typename A, typename B>
template<typename Fa , typename Fb >
auto ma::Either< A, B >::fold ( Fa  fa,
Fb  fb 
) -> std::result_of_t<Fa(A)>
inline

Reduces Either<A, B> to single value via two function objects.

Parameters
faFunction object that can be applied to an A.
fbFunction object that can be applied to a B.
Returns
Result of either fa(a) or fb(b) depending on which kind of value is contained.

Note that both fa and fb must have the same return type when applied to their respective arguments.

◆ isLeft()

template<typename A, typename B>
bool ma::Either< A, B >::isLeft ( ) const
inline

Checks whether an A is stored.

Returns
true if this Either<A, B> contains an A value.

◆ isRight()

template<typename A, typename B>
bool ma::Either< A, B >::isRight ( ) const
inline

Checks whether a B is stored.

Returns
true if this Either<A, B> contains a B value.

◆ leftJoin()

template<typename A, typename B>
template<class AA = A>
auto ma::Either< A, B >::leftJoin ( ) const -> typename std::enable_if< std::is_same<Either<typename AA::left_type, typename AA::right_type>, left_type>::value && std::is_same<right_type, typename AA::right_type>::value, Either<typename AA::left_type, right_type>>::type
inline

Joins instance of Either through left.

Only enabled on objects of the form Either<Either<C, B>, B>.

Returns
Flattened representation Either<C, B>

Ignore the dummy template argument, it is used to enable/disable this method.

◆ map() [1/2]

template<typename A, typename B>
template<typename Fb >
auto ma::Either< A, B >::map ( Fb  fb) -> Either<A, std::result_of_t<Fb(B)>>
inline

Applies supplied function to stored B value if one is available and wraps the result in Either.

Parameters
fbFunction object. F::operator() when called with B&& has return type Either<A, C>.
Returns
If this object contains a B value, the result of fb(b) is stored in the returned either. Otherwise, the pre-existing A value is copied into the return value.

◆ map() [2/2]

template<typename A, typename B>
template<typename Fb >
auto ma::Either< A, B >::map ( Fb  fb) const -> Either<A, std::result_of_t<Fb(B)>>
inline

Applies supplied function to stored B value if one is available and wraps result in Either.

Parameters
fbFunction object. F::operator() callable with const B& and non-void return type.
Returns
If this object contains a B value, the result of fb(b) is stored in the returned either. Otherwise, the pre-existing A value is copied into the return value.

◆ merge()

template<typename A, typename B>
template<class Dummy = A>
auto ma::Either< A, B >::merge ( ) const -> typename std::enable_if<std::is_same<A, B>::value, const Dummy&>::type
inline

If both left and right have the same type, allows merging to common type.

Returns
Either left or right, depending on which one is set. The purpose of the template argument Dummy is to allow SFINAE.

◆ mirror()

template<typename A, typename B>
Either<B, A> ma::Either< A, B >::mirror ( ) const
inline

Swaps left and right, preserving the stored value.

Returns
Copy of this either instance with A and B mirrored.

◆ recover()

template<typename A, typename B>
template<typename Fa >
B ma::Either< A, B >::recover ( Fa  fa) const
inline
Parameters
FaFunction object. F::operator() when called with A value has return type B.
Returns
Right value if contained, otherwise result of applying Fa to a.

◆ rightJoin()

template<typename A, typename B>
template<class BB = B>
auto ma::Either< A, B >::rightJoin ( ) const -> typename std::enable_if< std::is_same<Either<typename BB::left_type, typename BB::right_type>, right_type>::value && std::is_same<left_type, typename BB::left_type>::value, Either<left_type, typename BB::right_type>>::type
inline

Joins instance of Either through right.

Only enabled on objects of the form Either<A, Either<A, C>>.

Returns
Flattened representation Either<A, C>

Ignore the dummy template argument, it is used to enable/disable this method.

◆ toMaybe()

template<typename A, typename B>
Maybe<B> ma::Either< A, B >::toMaybe ( ) const
inline

If a B is contained, returns Just(B).

Otherwise returns Nothing.

Returns
Maybe<B> containing either the B or nothing.