Maybe

SetoidFunctorApplyApplicativeAltPlusAlternativeChainMonadFoldableExtendFilterable
The Maybe type is one of the most popular data types available. It is fundamental to learning about functional error handling and representing missing values. A Maybe value can be either Just a value or Nothing. The Just data constructor is used for wrapping present values while the Nothing constructor is used when a value is absent. Both constructors produce objects that share the same API which makes it easy to manipulate optional values without null checking or exception handling.
How to import
import { Maybe, Just, Nothing } from 'purify-ts/Maybe'
Without Maybe
// Hard to chain additional transformations
// Doesn't protect against falsy values like empty string or 0

const config: Config | null = getConfig()

const port = config && config.port
    ? parseInt(config.port)
    : 8080
Without Maybe (since TS 3.7 / ES2020)
// Still hard to chain additional transformations
// This is a valid alternative if you don't mind the syntax

const port = parseInt(getConfig()?.port ?? '8080')
With Maybe
const port = getConfig()
    .chain(x => x.port)
    .map(parseInt)
    .orDefault(8080)

Constructors

Just
a -> Maybe a<T>(value: T): Maybe<T>
Constructs a Just. Represents an optional value that exists.
Just(10)
Just(10) // Maybe<number>
Nothing
Nothing doesn't have a constructor, instead you can use it directly as a value. Represents a missing value, you can think of it as a smart 'null'.
Nothing
Nothing // Maybe<never>

Static methods

of
a -> Maybe a<T>(value: T): Maybe<T>
Takes a value and wraps it in a `Just`.
Maybe.of(10)
Just(10)
empty
() -> Maybe a(): Maybe<never>
Returns `Nothing`.
Maybe.empty()
Nothing
zero
() -> Maybe a(): Maybe<never>
Returns `Nothing`.
Maybe.zero()
Nothing
fromNullable
<T>(value?: T): Maybe<T>
Takes a value and returns `Nothing` if the value is null or undefined, otherwise a `Just` is returned.
Maybe.fromNullable(null)
Maybe.fromNullable(10)
Nothing
Just(10)
fromFalsy
<T>(value?: T): Maybe<T>
Takes a value and returns Nothing if the value is falsy, otherwise a Just is returned.
Maybe.fromFalsy('')
Maybe.fromFalsy(0)
Nothing
Nothing
fromPredicate
(a -> Bool) -> a -> Maybe a<T>(pred: (value: T) => boolean, value: T): Maybe<T>
Takes a predicate and a value, passes the value to the predicate and returns a Just if it returns true, otherwise a Nothing is returned
Maybe.fromPredicate(x => x > 0, 5)
Maybe.fromPredicate(x => x > 0, -1)
Just(5)
Nothing
catMaybes
[Maybe a] -> [a]<T>(list: Maybe<T>[]): T[]
Returns only the `Just` values in a list.
Maybe.catMaybes([Just(5), Nothing, Just(10)])
[5, 10]
mapMaybe
(a -> Maybe b) -> [a] -> [b]<T, U>(f: (value: T) => Maybe<U>, list: T[]): U[]
Maps over a list of values and returns a list of all resulting `Just` values.
Maybe.mapMaybe(x => isNaN(x) ? Nothing : Just(parseInt(x)), ['1', 'Apple', '3'])
[1, 3]
sequence
[Maybe a] -> Maybe [a]<T>(maybes: Maybe<T>[]): Maybe<T[]>
Turns a list of `Maybe`s into an `Maybe` of list if all items are `Just`.
Maybe.sequence([Just(1), Just(5), Just(10)])
Maybe.sequence([Just(1), Nothing, Just(10)])
Just([1, 5, 10])
Nothing
encase
<T>(throwsF: () => T): Maybe<T>
Calls a function that may throw and wraps the result in a `Just` if successful or `Nothing` if an error is caught.
Maybe.encase(() => { throw Error('Always fails') })
Maybe.encase(() => 10)
Nothing
Just(10)
isMaybe
<T>(x: unknown): x is Maybe<T>
Maybe.isMaybe(null)
Maybe.isMaybe(Just(10))
false
true

Instance methods

isJust
Maybe a ~> Bool(): boolean
Returns true if `this` is `Just`, otherwise it returns false.
Just(5).isJust()
Nothing.isJust()
true
false
isNothing
Maybe a ~> Bool(): this is Maybe<never>
Returns true if `this` is `Nothing`, otherwise it returns false.
Just(5).isNothing()
Nothing.isNothing()
false
true
caseOf
<U>(patterns: {Just: (value: T) => U, Nothing: () => U} | {_: () => U}): U
Structural pattern matching for `Maybe` in the form of a function.
Just(5).caseOf({ Just: x => x + 1, Nothing: () => 0 })
Nothing.caseOf({ Just: x => x + 1, Nothing: () => 0 })
Nothing.caseOf({ _: () => 'anything'}) // wildcard
6
0
'anything'
equals
Maybe a ~> Maybe a -> Bool(other: Maybe<T>): boolean
Compares the values inside `this` and the argument, returns true if both are Nothing or if the values are equal.
Just(5).equals(Just(5))
Just(5).equals(Just(10))
Just(5).equals(Nothing)
true
false
false
map
Maybe a ~> (a -> b) -> Maybe b<U>(f: (value: T) => U): Maybe<U>
Transforms the value inside `this` with a given function. Returns `Nothing` if `this` is `Nothing`.
Just(5).map(x => x + 1)
Nothing.map(x => x + 1)
Just(6)
Nothing
ap
Maybe a ~> Maybe (a -> b) -> Maybe b<U>(maybeF: Maybe<(value: T) => U>): Maybe<U>.
Maps `this` with a `Maybe` function
Just(5).ap(Just(x => x + 1))
Just(5).ap(Nothing)
Nothing.ap(Just(x => x + 1))
Nothing.ap(Nothing)
Just(6)
Nothing
Nothing
Nothing
alt
Maybe a ~> Maybe a -> Maybe a(other: Maybe<T>): Maybe<T>
Returns the first `Just` between `this` and another `Maybe` or `Nothing` if both `this` and the argument are `Nothing`.
Just(5).alt(Just(6))
Just(5).alt(Nothing)
Nothing.alt(Just(5))
Nothing.alt(Nothing)
Just(5)
Just(5)
Just(5)
Nothing
altLazy
Maybe a ~> (() -> Maybe a) -> Maybe a(other: () => Maybe<T>): Maybe<T>
Lazy version of `alt`.
chain
Maybe a ~> (a -> Maybe b) -> Maybe b<U>(f: (value: T) => Maybe<U>): Maybe<U>
Transforms `this` with a function that returns a `Maybe`. Useful for chaining many computations that may result in a missing value.
Just(5).chain(x => Just(x + 1))
Nothing.chain(x => Just(x + 1))
Just(6)
Nothing
chainNullable
<U>(f: (value: T) => U | undefined | null | void): Maybe<U>
Transforms `this` with a function that returns a nullable value. Equivalent to `m.chain(x => Maybe.fromNullable(f(x)))`.
Just({prop: null}).chainNullable(x => x.prop)
Just(5).chainNullable(x => x + 1)
Nothing
Just(6)
join
Maybe (Maybe a) ~> Maybe a<U>(this: Maybe<Maybe<U>>): Maybe<U>
Flattens nested Maybes. `m.join()` is equivalent to `m.chain(x => x)`.
Just(Just(5)).join()
Nothing.join()
Just(5)
Nothing
reduce
Maybe a ~> ((b, a) -> b, b) -> b<U>(reducer: (accumulator: U, value: T) => U, initialValue: U): U
Takes a reducer and an initial value and returns the initial value if `this` is `Nothing` or the result of applying the function to the initial value and the value inside `this`.
Just(5).reduce((acc, x) => x * acc, 2)
Nothing.reduce((acc, x) => x * acc, 0)
10
0
extend
Maybe a ~> (Maybe a -> b) -> Maybe b<U>(f: (value: Maybe<T>) => U): Maybe<U>
Returns `this` if it's `Nothing`, otherwise it returns the result of applying the function argument to `this` and wrapping it in a `Just`.
Just(5).extend(x => x.isJust())
Nothing.extend(x => x.isJust())
Just(true)
Nothing
unsafeCoerce
Maybe a ~> a (): T
Returns the value inside `this` or throws an error if `this` is `Nothing`.
Just(5).unsafeCoerce()
Nothing.unsafeCoerce()
5
// Uncaught Error: Maybe#unsafeCoerce was ran on a Nothing
orDefault
Maybe a ~ a -> a(defaultValue: T): T
Returns the default value if `this` is `Nothing`, otherwise it returns the value inside `this`.
Just(5).orDefault(0)
Nothing.orDefault(0)
5
0
orDefaultLazy
Maybe a ~ (() -> a) -> a(getDefaultValue: () => T): T
Lazy version of `orDefault`. Takes a function that returns the default value, that function will be called only if `this` is `Nothing`
Just(5).orDefaultLazy(() => expensiveComputation())
Nothing.orDefaultLazy(() => 0)
5 // expensiveComputation is never called
0
mapOrDefault
Maybe a ~> (a -> b) -> b -> b<U>(f: (value: T) => U, defaultValue: U): U
Maps over `this` and returns the resulting value or returns the default value if `this` is `Nothing`.
Just(5).mapOrDefault(x => x + 1, 0)
Nothing.mapOrDefault(x => x + 1, 0)
6
0
filter
Maybe a ~> (a -> Bool) -> Maybe a(pred: (value: T) => boolean): Maybe<T>
Takes a predicate function and returns `this` if the predicate returns true or Nothing if it returns false.
Just(5).filter(x => x > 1)
Just('apple').filter(x => x === 'banana')
Just(5)
Nothing
extract
(): T | undefined
Returns the value inside `this` or undefined if `this` is `Nothing`. Use `extractNullable` if you need a null returned instead.
Just(5).extract()
Nothing.extract()
5
undefined
extractNullable
(): T | null
Returns the value inside `this` or null if `this` is `Nothing`. Use `extract` if you need an undefined returned instead.
Just(5).extractNullable()
Nothing.extractNullable()
5
null
toList
Maybe a ~> [a](): T[]
Returns empty list if the `Maybe` is `Nothing` or a list where the only element is the value of `Just`.
Just(5).toList()
Nothing.toList()
[5]
[]
toEither
Maybe a ~> e -> Either e a<L>(left: L): Either<L, T>
Constructs a `Right` from a `Just` or a `Left` with a provided left value if `this` is `Nothing`.
Just(5).toEither('Error')
Nothing.toEither('Error')
Right(5)
Left('Error')
ifJust
(effect: (value: T) => any): this
Runs an effect if `this` is `Just`, returns `this` to make chaining other methods possible.
Just(5).ifJust(() => console.log('success'))
Nothing.ifJust(() => console.log('success'))
// success
ifNothing
(effect: (value: T) => any): this
Runs an effect if `this` is `Nothing`, returns `this` to make chaining other methods possible.
Just(5).ifNothing(() => console.log('failure'))
Nothing.ifNothing(() => console.log('failure'))
// failure