Skip to content

Commit

Permalink
feat(maybe): monad functor
Browse files Browse the repository at this point in the history
  • Loading branch information
Hfutsora committed Jul 27, 2022
1 parent 9e5ff23 commit b123cfc
Showing 1 changed file with 32 additions and 0 deletions.
32 changes: 32 additions & 0 deletions src/Maybe.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Predicate } from './Predicate'
import { Lazy, constNull, identity, constUndefined } from './function'
import { Either, right, left } from './Either'
import { Monad1 } from './Functors/Monad'
import { pipe } from './Pipe'

export interface None {
readonly _tag: 'None'
Expand All @@ -13,6 +15,15 @@ export interface Some<A> {

export type Maybe<A> = None | Some<A>

export const MaybeKind = Symbol('Maybe')
export type MaybeKind = typeof MaybeKind

declare module './Functors/HKT' {
interface Kinded<T> {
readonly [MaybeKind]: Maybe<T[0]>
}
}

/**
* Returns whether the maybe is `None` or not.
*
Expand Down Expand Up @@ -92,6 +103,11 @@ export const ap = <A>(ma: Maybe<A>) => <B>(fab: Maybe<(a: A) => B>): Maybe<B> =>
*/
export const empty = () => none

/**
* Alias of `empty`.
*/
export const zero = empty

/**
* Takes a predicate function and a `Maybe`, returns the `Maybe` if it's `Some` and the predicate returns true, otherwise returns `None`.
*
Expand Down Expand Up @@ -264,3 +280,19 @@ export const tryCatch = <A>(f: Lazy<A>): Maybe<A> => {
*/
export const equals = <A>(a: Maybe<A>, b: Maybe<A>): boolean =>
a === b || (isNone(a) ? isNone(b) : isSome(b) && a.value === b.value)

// none-pipeables
const _map: Monad1<MaybeKind>['map'] = (ma, f) => pipe(ma, map(f))
const _ap: Monad1<MaybeKind>['ap'] = (fab, fa) => pipe(fab, ap(fa))
const _chain: Monad1<MaybeKind>['chain'] = (ma, f) => pipe(ma, chain(f))

/**
* Monad Functor
*/
export const Monad: Monad1<MaybeKind> = {
URI: MaybeKind,
of,
map: _map,
ap: _ap,
chain: _chain
}

0 comments on commit b123cfc

Please sign in to comment.