import { Applicative, Applicative1, Applicative2, Applicative2C, } from 'fp-ts/lib/Applicative' import { HKT, Kind, Kind2, URIS, URIS2 } from 'fp-ts/lib/HKT' import * as O from 'fp-ts/lib/Option' import { pipe } from 'fp-ts/lib/pipeable' import { isNil } from '@monorail/sharedHelpers/typeGuards' import { ReactRenderable } from '@monorail/sharedHelpers/typeLevel' export * from 'fp-ts/lib/Option' /** * type guard for Option */ export const isOption = (x: unknown): x is O.Option => { if (!isNil(x)) { const x_ = x as { value?: A; _tag: 'Some' | 'None' } return (!isNil(x_.value) && x_._tag === 'Some') || x_._tag === 'None' } return false } /** * A specialized (partially applied with a null default) version of Option's * `fold` method that returns null when given a `None` or a `ReactNode` when * given a `Some` */ export const renderOnSome = ( a: O.Option, onSome: (a: A) => ReactRenderable, ): ReactRenderable => O.fold(() => null, onSome)(a) /** * Partially applied version of `getOrElse` providing an empty string * as the default argument */ export const getOrEmptyString = O.getOrElse(() => '') /** * Folds an option down into either an empty array or a single-element array containing * the value from within the Some. Useful in conjunction with the spread operator. */ export const toArray: (fa: O.Option) => Array = fa => pipe( fa, O.fold( () => [], a => [a], ), ) /** * Traverse over an Option into an applicative. * * usage example: * * ```ts * import { pipe } from 'fp-ts/lib/pipeable' * import * as IO from 'fp-ts/lib/IO' * import { newIO } from '@monorail/sharedHelpers/fp-ts-ext/IO' * * const foo: Option = some("foo") * * pipe( * foo, * opTraverse(IO.io)(s => newIO(() => document.write(s))) * )() * ``` * @param Ap Applicative instance * @param f function that returns an instance of an Ap applicative */ export function opTraverse( Ap: Applicative2C, ): ( f: (a: A) => Kind2, ) => (o: O.Option) => Kind2> export function opTraverse( Ap: Applicative2, ): ( f: (a: A) => Kind2, ) => (o: O.Option) => Kind2> export function opTraverse( Ap: Applicative1, ): (f: (a: A) => Kind) => (o: O.Option) => Kind> export function opTraverse( Ap: Applicative, ): (f: (a: A) => HKT) => (o: O.Option) => HKT> { return f => oA => O.option.traverse(Ap)(oA, f) }