Overview
If you have worked with JavaScript at all in the past, it is very likely that you have come across a TypeError at
some time (other languages will throw similarly named errors in such a case). Usually this happens because some
method returns null or undefined when you were not expecting it and thus not dealing with that possibility in
your client code.
const as: Array<string> = []
as[0].trim() // throws TypeError: Cannot read property 'trim' of undefined
fp-ts models the absence of values through the Option datatype similar to how Scala, Haskell and other FP languages
handle optional values. A value of null or undefined is often abused to represent an absent optional value.
Option<A> is a container for an optional value of type A. If the value of type A is present, the Option<A> is
an instance of Some<A>, containing the present value of type A. If the value is absent, the Option<A> is an
instance of None<A>.
An option could be looked at as a collection or foldable structure with either one or zero elements. Another way to look at option is: it represents the effect of a possibly failing computation.
import { Option, some, none } from 'fp-ts/lib/Option'
const someValue: Option<string> = some('foo')
const emptyValue: Option<string> = none
Let’s write a function that may or not give us a string, thus returning Option<string>
const head = (as: Array<string>): Option<string> => {
return as.length > 0 ? some(as[0]) : none
}
Using getOrElse we can provide a default value "No value" when the optional argument None does not exist:
const value1 = head(['foo', 'bar']) // some('foo)
const value2 = head([]) // none
value1.getOrElse('No value') // 'foo'
value2.getOrElse('No value') // 'No value'
Checking whether option has value:
value1.isNone() // false
value2.isNone() // true
We can pattern match using the fold method
const number: Option<number> = some(3)
const noNumber: Option<number> = none
number.fold(1, n => n * 3) // 9
noNumber.fold(1, n => n * 3) // 1
You can chain several possibly failing computations using the chain method
const inverse = (n: number): Option<number> => {
return n === 0 ? none : some(1 / n)
}
number.chain(inverse) // 1/3
noNumber.chain(inverse) // none
some(0).chain(inverse) // none
Computing over independent values
const sum = (a: number) => (b: number): number => a + b
const sumLifted = (oa: Option<number>, ob: Option<number>): Option<number> => ob.ap(oa.map(sum))
sumLifted(some(1), some(2)) // some(3)
sumLifted(some(1), none) // none
Table of contents
- Option (type alias)
- URI (type alias)
- None (class)
- map (method)
- mapNullable (method)
- ap (method)
- ap_ (method)
- chain (method)
- reduce (method)
- alt (method)
- orElse (method)
- extend (method)
- fold (method)
- foldL (method)
- getOrElse (method)
- getOrElseL (method)
- toNullable (method)
- toUndefined (method)
- inspect (method)
- toString (method)
- contains (method)
- isNone (method)
- isSome (method)
- exists (method)
- filter (method)
refine(method)
- Some (class)
- map (method)
- mapNullable (method)
- ap (method)
- ap_ (method)
- chain (method)
- reduce (method)
- alt (method)
- orElse (method)
- extend (method)
- fold (method)
- foldL (method)
- getOrElse (method)
- getOrElseL (method)
- toNullable (method)
- toUndefined (method)
- inspect (method)
- toString (method)
- contains (method)
- isNone (method)
- isSome (method)
- exists (method)
- filter (method)
- refine (method)
- URI (constant)
- none (constant)
- option (constant)
- fromEither (function)
- fromNullable (function)
- fromPredicate (function)
fromRefinement(function)- getApplyMonoid (function)
- getApplySemigroup (function)
- getFirstMonoid (function)
- getLastMonoid (function)
- getMonoid (function)
- getOrd (function)
- getRefinement (function)
- getSetoid (function)
- isNone (function)
- isSome (function)
- some (function)
- tryCatch (function)
Option (type alias)
Signature
export type Option<A> = None<A> | Some<A>
Added in v1.0.0
URI (type alias)
Signature
export type URI = typeof URI
None (class)
Signature
export class None<A> {
private constructor() { ... }
...
}
map (method)
Takes a function f and an Option of A. Maps f either on None or Some, Option’s data constructors. If it
maps on Some then it will apply the f on Some’s value, if it maps on None it will return None.
Signature
map<B>(f: (a: A) => B): Option<B> { ... }
Example
import { some } from 'fp-ts/lib/Option'
assert.deepStrictEqual(some(1).map(n => n * 2), some(2))
mapNullable (method)
Maps f over this Option’s value. If the value returned from f is null or undefined, returns None
Signature
mapNullable<B>(f: (a: A) => B | null | undefined): Option<B> { ... }
Example
import { none, some } from 'fp-ts/lib/Option'
interface Foo {
bar?: {
baz?: string
}
}
assert.deepStrictEqual(
some<Foo>({ bar: { baz: 'quux' } })
.mapNullable(foo => foo.bar)
.mapNullable(bar => bar.baz),
some('quux')
)
assert.deepStrictEqual(
some<Foo>({ bar: {} })
.mapNullable(foo => foo.bar)
.mapNullable(bar => bar.baz),
none
)
assert.deepStrictEqual(
some<Foo>({})
.mapNullable(foo => foo.bar)
.mapNullable(bar => bar.baz),
none
)
ap (method)
ap, some may also call it “apply”. Takes a function fab that is in the context of Option, and applies that
function to this Option’s value. If the Option calling ap is none it will return none.
Signature
ap<B>(fab: Option<(a: A) => B>): Option<B> { ... }
Example
import { some, none } from 'fp-ts/lib/Option'
assert.deepStrictEqual(some(2).ap(some((x: number) => x + 1)), some(3))
assert.deepStrictEqual(none.ap(some((x: number) => x + 1)), none)
ap_ (method)
Flipped version of ap
Signature
ap_<B, C>(this: Option<(b: B) => C>, fb: Option<B>): Option<C> { ... }
Example
import { some, none } from 'fp-ts/lib/Option'
assert.deepStrictEqual(some((x: number) => x + 1).ap_(some(2)), some(3))
assert.deepStrictEqual(none.ap_(some(2)), none)
chain (method)
Returns the result of applying f to this Option’s value if this Option is nonempty. Returns None if this
Option is empty. Slightly different from map in that f is expected to return an Option (which could be
None)
Signature
chain<B>(f: (a: A) => Option<B>): Option<B> { ... }
reduce (method)
Signature
reduce<B>(b: B, f: (b: B, a: A) => B): B { ... }
alt (method)
alt short for alternative, takes another Option. If this Option is a Some type then it will be returned, if
it is a None then it will return the next Some if it exist. If both are None then it will return none.
Signature
alt(fa: Option<A>): Option<A> { ... }
Example
import { Option, some, none } from 'fp-ts/lib/Option'
assert.deepStrictEqual(some(2).alt(some(4)), some(2))
const fa: Option<number> = none
assert.deepStrictEqual(fa.alt(some(4)), some(4))
orElse (method)
Lazy version of alt
Signature
orElse(fa: Lazy<Option<A>>): Option<A> { ... }
Example
import { some } from 'fp-ts/lib/Option'
assert.deepStrictEqual(some(1).orElse(() => some(2)), some(1))
Added in v1.6.0
extend (method)
Signature
extend<B>(f: (ea: Option<A>) => B): Option<B> { ... }
fold (method)
Applies a function to each case in the data structure
Signature
fold<B>(b: B, onSome: (a: A) => B): B { ... }
Example
import { none, some } from 'fp-ts/lib/Option'
assert.strictEqual(some(1).fold('none', a => `some: ${a}`), 'some: 1')
assert.strictEqual(none.fold('none', a => `some: ${a}`), 'none')
foldL (method)
Lazy version of fold
Signature
foldL<B>(onNone: () => B, onSome: (a: A) => B): B { ... }
getOrElse (method)
Returns the value from this Some or the given argument if this is a None
Signature
getOrElse(a: A): A { ... }
Example
import { Option, none, some } from 'fp-ts/lib/Option'
assert.strictEqual(some(1).getOrElse(0), 1)
const fa: Option<number> = none
assert.strictEqual(fa.getOrElse(0), 0)
getOrElseL (method)
Lazy version of getOrElse
Signature
getOrElseL(f: () => A): A { ... }
toNullable (method)
Returns the value from this Some or null if this is a None
Signature
toNullable(): A | null { ... }
toUndefined (method)
Returns the value from this Some or undefined if this is a None
Signature
toUndefined(): A | undefined { ... }
inspect (method)
Signature
inspect(): string { ... }
toString (method)
Signature
toString(): string { ... }
contains (method)
Returns true if the option has an element that is equal (as determined by S) to a, false otherwise
Signature
contains(S: Setoid<A>, a: A): boolean { ... }
isNone (method)
Returns true if the option is None, false otherwise
Signature
isNone(): this is None<A> { ... }
isSome (method)
Returns true if the option is an instance of Some, false otherwise
Signature
isSome(): this is Some<A> { ... }
exists (method)
Returns true if this option is non empty and the predicate p returns true when applied to this Option’s value
Signature
exists(p: (a: A) => boolean): boolean { ... }
filter (method)
Returns this option if it is non empty and the predicate p return true when applied to this Option’s value.
Otherwise returns None
Signature
filter<B extends A>(p: Refinement<A, B>): Option<B>
filter(p: Predicate<A>): Option<A> { ... }
refine (method)
Use filter instead.
Returns this option refined as Option<B> if it is non empty and the refinement returns true when applied to
this Option’s value. Otherwise returns None
Signature
refine<B extends A>(refinement: Refinement<A, B>): Option<B> { ... }
Added in v1.3.0
Some (class)
Signature
export class Some<A> {
constructor(readonly value: A) { ... }
...
}
map (method)
Signature
map<B>(f: (a: A) => B): Option<B> { ... }
mapNullable (method)
Signature
mapNullable<B>(f: (a: A) => B | null | undefined): Option<B> { ... }
ap (method)
Signature
ap<B>(fab: Option<(a: A) => B>): Option<B> { ... }
ap_ (method)
Signature
ap_<B, C>(this: Option<(b: B) => C>, fb: Option<B>): Option<C> { ... }
chain (method)
Signature
chain<B>(f: (a: A) => Option<B>): Option<B> { ... }
reduce (method)
Signature
reduce<B>(b: B, f: (b: B, a: A) => B): B { ... }
alt (method)
Signature
alt(fa: Option<A>): Option<A> { ... }
orElse (method)
Signature
orElse(fa: Lazy<Option<A>>): Option<A> { ... }
extend (method)
Signature
extend<B>(f: (ea: Option<A>) => B): Option<B> { ... }
fold (method)
Signature
fold<B>(b: B, onSome: (a: A) => B): B { ... }
foldL (method)
Signature
foldL<B>(onNone: () => B, onSome: (a: A) => B): B { ... }
getOrElse (method)
Signature
getOrElse(a: A): A { ... }
getOrElseL (method)
Signature
getOrElseL(f: () => A): A { ... }
toNullable (method)
Signature
toNullable(): A | null { ... }
toUndefined (method)
Signature
toUndefined(): A | undefined { ... }
inspect (method)
Signature
inspect(): string { ... }
toString (method)
Signature
toString(): string { ... }
contains (method)
Signature
contains(S: Setoid<A>, a: A): boolean { ... }
isNone (method)
Signature
isNone(): this is None<A> { ... }
isSome (method)
Signature
isSome(): this is Some<A> { ... }
exists (method)
Signature
exists(p: (a: A) => boolean): boolean { ... }
filter (method)
Signature
filter<B extends A>(p: Refinement<A, B>): Option<B>
filter(p: Predicate<A>): Option<A> { ... }
refine (method)
Signature
refine<B extends A>(refinement: Refinement<A, B>): Option<B> { ... }
URI (constant)
Signature
export const URI = ...
none (constant)
Signature
export const none: Option<never> = ...
Added in v1.0.0
option (constant)
Signature
export const option: Monad1<URI> &
Foldable2v1<URI> &
Plus1<URI> &
Traversable2v1<URI> &
Alternative1<URI> &
Extend1<URI> &
Compactable1<URI> &
Filterable1<URI> &
Witherable1<URI> = ...
Added in v1.0.0
fromEither (function)
Constructs a new Option from a Either. If the value is a Left, returns None, otherwise returns the inner
value wrapped in a Some
Signature
export const fromEither = <L, A>(fa: Either<L, A>): Option<A> => ...
Example
import { none, some, fromEither } from 'fp-ts/lib/Option'
import { left, right } from 'fp-ts/lib/Either'
assert.deepStrictEqual(fromEither(left(1)), none)
assert.deepStrictEqual(fromEither(right(1)), some(1))
Added in v1.0.0
fromNullable (function)
Constructs a new Option from a nullable type. If the value is null or undefined, returns None, otherwise
returns the value wrapped in a Some
Signature
export const fromNullable = <A>(a: A | null | undefined): Option<A> => ...
Example
import { none, some, fromNullable } from 'fp-ts/lib/Option'
assert.deepStrictEqual(fromNullable(undefined), none)
assert.deepStrictEqual(fromNullable(null), none)
assert.deepStrictEqual(fromNullable(1), some(1))
Added in v1.0.0
fromPredicate (function)
Signature
export function fromPredicate<A, B extends A>(predicate: Refinement<A, B>): (a: A) => Option<B>
export function fromPredicate<A>(predicate: Predicate<A>): (a: A) => Option<A> { ... }
Example
import { none, some, fromPredicate } from 'fp-ts/lib/Option'
const positive = fromPredicate((n: number) => n >= 0)
assert.deepStrictEqual(positive(-1), none)
assert.deepStrictEqual(positive(1), some(1))
Added in v1.0.0
fromRefinement (function)
Use fromPredicate instead.
Refinement version of fromPredicate
Signature
export const fromRefinement = <A, B extends A>(refinement: Refinement<A, B>) => (a: A): Option<B> => ...
Added in v1.3.0
getApplyMonoid (function)
Signature
export const getApplyMonoid = <A>(M: Monoid<A>): Monoid<Option<A>> => ...
Added in v1.7.0
getApplySemigroup (function)
Apply semigroup
| x | y | concat(x, y) |
|---|---|---|
| none | none | none |
| some(a) | none | none |
| none | some(a) | none |
| some(a) | some(b) | some(concat(a, b)) |
Signature
export const getApplySemigroup = <A>(S: Semigroup<A>): Semigroup<Option<A>> => ...
Example
import { getApplySemigroup, some, none } from 'fp-ts/lib/Option'
import { semigroupSum } from 'fp-ts/lib/Semigroup'
const S = getApplySemigroup(semigroupSum)
assert.deepStrictEqual(S.concat(none, none), none)
assert.deepStrictEqual(S.concat(some(1), none), none)
assert.deepStrictEqual(S.concat(none, some(1)), none)
assert.deepStrictEqual(S.concat(some(1), some(2)), some(3))
Added in v1.7.0
getFirstMonoid (function)
Monoid returning the left-most non-None value
| x | y | concat(x, y) |
|---|---|---|
| none | none | none |
| some(a) | none | some(a) |
| none | some(a) | some(a) |
| some(a) | some(b) | some(a) |
Signature
export const getFirstMonoid = <A = never>(): Monoid<Option<A>> => ...
Example
import { getFirstMonoid, some, none } from 'fp-ts/lib/Option'
const M = getFirstMonoid<number>()
assert.deepStrictEqual(M.concat(none, none), none)
assert.deepStrictEqual(M.concat(some(1), none), some(1))
assert.deepStrictEqual(M.concat(none, some(1)), some(1))
assert.deepStrictEqual(M.concat(some(1), some(2)), some(1))
Added in v1.0.0
getLastMonoid (function)
Monoid returning the right-most non-None value
| x | y | concat(x, y) |
|---|---|---|
| none | none | none |
| some(a) | none | some(a) |
| none | some(a) | some(a) |
| some(a) | some(b) | some(b) |
Signature
export const getLastMonoid = <A = never>(): Monoid<Option<A>> => ...
Example
import { getLastMonoid, some, none } from 'fp-ts/lib/Option'
const M = getLastMonoid<number>()
assert.deepStrictEqual(M.concat(none, none), none)
assert.deepStrictEqual(M.concat(some(1), none), some(1))
assert.deepStrictEqual(M.concat(none, some(1)), some(1))
assert.deepStrictEqual(M.concat(some(1), some(2)), some(2))
Added in v1.0.0
getMonoid (function)
Monoid returning the left-most non-None value. If both operands are Somes then the inner values are
appended using the provided Semigroup
| x | y | concat(x, y) |
|---|---|---|
| none | none | none |
| some(a) | none | some(a) |
| none | some(a) | some(a) |
| some(a) | some(b) | some(concat(a, b)) |
Signature
export const getMonoid = <A>(S: Semigroup<A>): Monoid<Option<A>> => ...
Example
import { getMonoid, some, none } from 'fp-ts/lib/Option'
import { semigroupSum } from 'fp-ts/lib/Semigroup'
const M = getMonoid(semigroupSum)
assert.deepStrictEqual(M.concat(none, none), none)
assert.deepStrictEqual(M.concat(some(1), none), some(1))
assert.deepStrictEqual(M.concat(none, some(1)), some(1))
assert.deepStrictEqual(M.concat(some(1), some(2)), some(3))
Added in v1.0.0
getOrd (function)
The Ord instance allows Option values to be compared with
compare, whenever there is an Ord instance for
the type the Option contains.
None is considered to be less than any Some value.
Signature
export const getOrd = <A>(O: Ord<A>): Ord<Option<A>> => ...
Example
import { none, some, getOrd } from 'fp-ts/lib/Option'
import { ordNumber } from 'fp-ts/lib/Ord'
const O = getOrd(ordNumber)
assert.strictEqual(O.compare(none, none), 0)
assert.strictEqual(O.compare(none, some(1)), -1)
assert.strictEqual(O.compare(some(1), none), 1)
assert.strictEqual(O.compare(some(1), some(2)), -1)
assert.strictEqual(O.compare(some(1), some(1)), 0)
Added in v1.2.0
getRefinement (function)
Returns a refinement from a prism. This function ensures that a custom type guard definition is type-safe.
import { some, none, getRefinement } from 'fp-ts/lib/Option'
type A = { type: 'A' }
type B = { type: 'B' }
type C = A | B
const isA = (c: C): c is A => c.type === 'B' // <= typo but typescript doesn't complain
const isA = getRefinement<C, A>(c => (c.type === 'B' ? some(c) : none)) // static error: Type '"B"' is not assignable to type '"A"'
Signature
export const getRefinement = <A, B extends A>(getOption: (a: A) => Option<B>): Refinement<A, B> => ...
Added in v1.7.0
getSetoid (function)
Signature
export const getSetoid = <A>(S: Setoid<A>): Setoid<Option<A>> => ...
Example
import { none, some, getSetoid } from 'fp-ts/lib/Option'
import { setoidNumber } from 'fp-ts/lib/Setoid'
const S = getSetoid(setoidNumber)
assert.strictEqual(S.equals(none, none), true)
assert.strictEqual(S.equals(none, some(1)), false)
assert.strictEqual(S.equals(some(1), none), false)
assert.strictEqual(S.equals(some(1), some(2)), false)
assert.strictEqual(S.equals(some(1), some(1)), true)
Added in v1.0.0
isNone (function)
Returns true if the option is None, false otherwise
Signature
export const isNone = <A>(fa: Option<A>): fa is None<A> => ...
Added in v1.0.0
isSome (function)
Returns true if the option is an instance of Some, false otherwise
Signature
export const isSome = <A>(fa: Option<A>): fa is Some<A> => ...
Added in v1.0.0
some (function)
Signature
export const some = <A>(a: A): Option<A> => ...
Added in v1.0.0
tryCatch (function)
Transforms an exception into an Option. If f throws, returns None, otherwise returns the output wrapped in
Some
Signature
export const tryCatch = <A>(f: Lazy<A>): Option<A> => ...
Example
import { none, some, tryCatch } from 'fp-ts/lib/Option'
assert.deepStrictEqual(
tryCatch(() => {
throw new Error()
}),
none
)
assert.deepStrictEqual(tryCatch(() => 1), some(1))
Added in v1.0.0