Skip to content

Instantly share code, notes, and snippets.

@mattiamanzati
Created May 14, 2019 10:20
Show Gist options
  • Save mattiamanzati/1092314c21f104274377a580e7005e3d to your computer and use it in GitHub Desktop.
Save mattiamanzati/1092314c21f104274377a580e7005e3d to your computer and use it in GitHub Desktop.
import { Alt1, Alt, Alt2 } from 'fp-ts/lib/Alt'
import { Apply1, Apply, Apply2 } from 'fp-ts/lib/Apply'
import { Chain1, Chain, Chain2 } from 'fp-ts/lib/Chain'
import { Eq } from 'fp-ts/lib/Eq'
import { Extend1, Extend, Extend2 } from 'fp-ts/lib/Extend'
import { Foldable1, Foldable, Foldable2 } from 'fp-ts/lib/Foldable'
import { FoldableWithIndex1, FoldableWithIndex, FoldableWithIndex2 } from 'fp-ts/lib/FoldableWithIndex'
import { Functor1, Functor, Functor2 } from 'fp-ts/lib/Functor'
import { FunctorWithIndex, FunctorWithIndex2, FunctorWithIndex1 } from 'fp-ts/lib/FunctorWithIndex'
import { HKT, Type, URIS, URIS2, Type2 } from 'fp-ts/lib/HKT'
import { Magma } from 'fp-ts/lib/Magma'
import { Monoid } from 'fp-ts/lib/Monoid'
import { Ord } from 'fp-ts/lib/Ord'
import { Ordering } from 'fp-ts/lib/Ordering'
import { Show } from 'fp-ts/lib/Show'
import { Compactable1, Separated, Compactable, Compactable2 } from 'fp-ts/lib/Compactable'
import { Option, option, none, some } from 'fp-ts/lib/Option'
import { Either, either, right, left } from 'fp-ts/lib/Either'
import { Filterable1, Filterable, Filterable2 } from 'fp-ts/lib/Filterable'
import { Refinement, Predicate } from 'fp-ts/lib/function'
import {
FilterableWithIndex1,
PredicateWithIndex,
RefinementWithIndex,
FilterableWithIndex,
FilterableWithIndex2
} from 'fp-ts/lib/FilterableWithIndex'
import { Bifunctor2 } from 'fp-ts/lib/Bifunctor'
import { Profunctor2 } from 'fp-ts/lib/Profunctor'
import { Semigroupoid2 } from 'fp-ts/lib/Semigroupoid'
type Show2Methods<F extends URIS2, I> = I extends Show<Type2<F, any, any>> ? 'show' : never
type Eq2Methods<F extends URIS2, I, L, A> = I extends Eq<Type2<F, L, A>>
? 'equals'
: never
type Ord2Methods<F extends URIS2, I, L, A> = I extends Ord<Type2<F, L, A>>
? 'compare'
: never
type Magma2Methods<F extends URIS2, I, L, A> = I extends Magma<Type2<F, L, A>>
? 'concat'
: never
type Functor2Methods<F extends URIS2, I, L, A> = I extends Functor2<F>
? 'map'
: never
type FunctorWithIndex2Methods<F extends URIS2, I, L, A> = I extends FunctorWithIndex2<F, any>
? 'mapWithIndex'
: never
type Apply2Methods<F extends URIS2, I, L, A> = I extends Apply2<F>
? 'ap' | 'apFirst' | 'apSecond'
: never
type Chain2Methods<F extends URIS2, I, L, A> = I extends Chain2<F>
? 'chain' | 'flatten'
: never
type Extend2Methods<F extends URIS2, I, L, A> = I extends Extend2<F>
? 'extend' | 'duplicate'
: never
type Foldable2Methods<F extends URIS2, I, A> = I extends Foldable2<F>
? 'reduce' | 'foldMap' | 'reduceRight'
: never
type FoldableWithIndex2Methods<F extends URIS2, I, A> = I extends FoldableWithIndex2<F, any>
? 'reduceWithIndex' | 'foldMapWithIndex' | 'reduceRightWithIndex'
: never
type Alt2Methods<F extends URIS2, I, L, A> = I extends Alt2<F>
? 'alt'
: never
type Compactable2Methods<F extends URIS2, I, L> = I extends Compactable2<F>
? 'compact' | 'separate'
: never
type Filterable2Methods<F extends URIS2, I, L, A> = I extends Filterable2<F>
? 'filter' | 'filterMap' | 'partitionMap'
: {}
type FilterableWithIndex2Methods<F extends URIS2, I, L, A> = I extends FilterableWithIndex2<F, any>
? 'filterWithIndex' | 'filterMapWithIndex' | 'partitionWithIndex' | 'partitionMapWithIndex'
: never
type Bifunctor2Methods<F extends URIS2, I, L, A> = I extends Bifunctor2<F>
? 'bimap' | 'mapLeft'
: never
type Profunctor2Methods<F extends URIS2, I, L, A> = I extends Profunctor2<F>
? 'promap'
: never
type Semigroupoid2Methods<F extends URIS2, I, L, A> = I extends Semigroupoid2<F>
? 'compose'
: never
/**
* @since 2.0.0
*/
export interface Fluent2Defs<F extends URIS2, I, L, A> {
readonly I: I
readonly value: Type2<F, L, A>
show(this: Fluent2<F, Show<Type2<F, L, A>>, L, A>): string
equals(this: Fluent2<F, Eq<Type2<F, L, A>>, L, A>, that: Type2<F, L, A>): boolean
compare(this: Fluent2<F, Ord<Type2<F, L, A>>, L, A>, that: Type2<F, L, A>): Ordering
concat(this: Fluent2<F, Magma<Type2<F, L, A>>, L, A>, that: Type2<F, L, A>): Type2<F, L, A>
map<B>(this: Fluent2<F, Functor2<F>, L, A>, f: (a: A) => B): Fluent2<F, I, L, B>
mapWithIndex<Ix, B>(this: Fluent2<F, FunctorWithIndex2<F, Ix>, L, A>, f: (i: Ix, a: A) => B): Fluent2<F, I, L, B>
bimap<M, B>(this: Fluent2<F, Bifunctor2<F>, L, A>, f: (l: L) => M, g: (a: A) => B): Fluent2<F, I, M, B>
mapLeft<M>(this: Fluent2<F, Bifunctor2<F>, L, A>, f: (l: L) => M): Fluent2<F, I, M, A>
ap<B>(this: Fluent2<F, Apply2<F>, L, A>, fab: Type2<F, L, (a: A) => B>): Fluent2<F, I, L, B>
apFirst<B>(this: Fluent2<F, Apply2<F>, L, A>, that: Type2<F, L, B>): Fluent2<F, I, L, A>
apSecond<B>(this: Fluent2<F, Apply2<F>, L, A>, that: Type2<F, L, B>): Fluent2<F, I, L, B>
chain<B>(this: Fluent2<F, Chain2<F>, L, A>, f: (a: A) => Type2<F, L, B>): Fluent2<F, I, L, B>
flatten<A>(this: Fluent2<F, Chain2<F>, L, Type2<F, L, A>>): Fluent2<F, I, L, A>
extend<B>(this: Fluent2<F, Extend2<F>, L, A>, f: (fa: Type2<F, L, A>) => B): Fluent2<F, I, L, B>
duplicate(this: Fluent2<F, Extend2<F>, L, A>): Fluent2<F, I, L, Type2<F, L, A>>
reduce<B>(this: Fluent2<F, Foldable2<F>, L, A>, b: B, f: (b: B, a: A) => B): B
foldMap<M>(this: Fluent2<F, Foldable2<F>, L, A>, M: Monoid<M>): (f: (a: A) => M) => M
reduceRight<B>(this: Fluent2<F, Foldable2<F>, L, A>, b: B, f: (a: A, b: B) => B): B
reduceWithIndex<Ix, B>(this: Fluent2<F, FoldableWithIndex2<F, Ix>, L, A>, b: B, f: (i: Ix, b: B, a: A) => B): B
foldMapWithIndex<Ix, M>(this: Fluent2<F, FoldableWithIndex2<F, Ix>, L, A>, M: Monoid<M>): (i: Ix, f: (a: A) => M) => M
reduceRightWithIndex<Ix, B>(this: Fluent2<F, FoldableWithIndex2<F, Ix>, L, A>, b: B, f: (i: Ix, a: A, b: B) => B): B
alt(this: Fluent2<F, Alt2<F>, L, A>, that: () => Type2<F, L, A>): Fluent2<F, I, L, A>
compact<A>(this: Fluent2<F, Compactable2<F>, L, Option<A>>): Fluent2<F, I, L, A>
separate<A, B>(this: Fluent2<F, Compactable2<F>, L, Either<A, B>>): Separated<Type2<F, L, A>, Type2<F, L, B>>
filter<B extends A>(this: Fluent2<F, Filterable2<F>, L, A>, refinement: Refinement<A, B>): Fluent2<F, I, L, B>
filter(this: Fluent2<F, Filterable2<F>, L, A>, predicate: Predicate<A>): Fluent2<F, I, L, A>
filterMap<B>(this: Fluent2<F, Filterable2<F>, L, A>, f: (a: A) => Option<B>): Fluent2<F, I, L, B>
partition<B extends A>(
this: Fluent2<F, Filterable2<F>, L, A>,
refinement: Refinement<A, B>
): Separated<Type2<F, L, A>, Type2<F, L, B>>
partition(this: Fluent2<F, Filterable2<F>, L, A>, predicate: Predicate<A>): Separated<Type2<F, L, A>, Type2<F, L, A>>
partitionMap<RL, RR>(
this: Fluent2<F, Filterable2<F>, L, A>,
f: (a: A) => Either<RL, RR>
): Separated<Type2<F, L, RL>, Type2<F, L, RR>>
filterWithIndex<Ix>(
this: Fluent2<F, FilterableWithIndex2<F, Ix>, L, A>,
p: (i: Ix, a: A) => boolean
): Fluent2<F, I, L, A>
filterMapWithIndex<Ix, B>(
this: Fluent2<F, FilterableWithIndex2<F, Ix>, L, A>,
f: (i: Ix, a: A) => Option<B>
): Fluent2<F, I, L, B>
partitionWithIndex<Ix>(
this: Fluent2<F, FilterableWithIndex2<F, Ix>, L, A>,
p: (i: Ix, a: A) => boolean
): Separated<Type2<F, L, A>, Type2<F, L, A>>
partitionMapWithIndex<Ix, RL, RR>(
this: Fluent2<F, FilterableWithIndex2<F, Ix>, L, A>,
f: (i: Ix, a: A) => Either<RL, RR>
): Separated<Type2<F, L, RL>, Type2<F, L, RR>>
promap<H, B>(this: Fluent2<F, Profunctor2<F>, L, A>, f: (h: H) => L, g: (a: A) => B): Fluent2<F, I, H, B>
compose<B>(this: Fluent2<F, Semigroupoid2<F>, L, A>, that: Type2<F, A, B>): Fluent2<F, I, L, B>
}
type Fluent2<F extends URIS2, I, L, A> = Pick<Fluent2Defs<F, I, L, A>, Fluent2Keys<F, I, L, A>>
export type Fluent2Keys<F extends URIS2, I, L, A> = Show2Methods<F, I> &
Eq2Methods<F, I, L, A> &
Ord2Methods<F, I, L, A> &
Magma2Methods<F, I, L, A> &
Functor2Methods<F, I, L, A> &
FunctorWithIndex2Methods<F, I, L, A> &
Apply2Methods<F, I, L, A> &
Chain2Methods<F, I, L, A> &
Extend2Methods<F, I, L, A> &
Foldable2Methods<F, I, A> &
FoldableWithIndex2Methods<F, I, A> &
Alt2Methods<F, I, L, A> &
Compactable2Methods<F, L, I> &
Filterable2Methods<F, I, L, A> &
FilterableWithIndex2Methods<F, I, L, A> &
Bifunctor2Methods<F, I, L, A> &
Profunctor2Methods<F, I, L, A> &
Semigroupoid2Methods<F, I, L, A>
type Show1Methods<F extends URIS, I> = I extends Show<Type<F, any>> ? 'show' : never
type Eq1Methods<F extends URIS, I, A> = I extends Eq<Type<F, A>> ? 'equals' : never
type Ord1Methods<F extends URIS, I, A> = I extends Ord<Type<F, A>> ? 'compare' : never
type Magma1Methods<F extends URIS, I, A> = I extends Magma<Type<F, A>>
? 'concat'
: never
type Functor1Methods<F extends URIS, I, A> = I extends Functor1<F>
? 'map'
: never
type FunctorWithIndex1Methods<F extends URIS, I, A> = I extends FunctorWithIndex1<F, infer Ix>
? 'mapWithIndex'
: never
type Apply1Methods<F extends URIS, I, A> = I extends Apply1<F>
? 'ap' | 'apFirst' | 'apSecond'
: never
type Chain1Methods<F extends URIS, I, A> = I extends Chain1<F>
? 'chain' | 'flatten'
: never
type Extend1Methods<F extends URIS, I, A> = I extends Extend1<F>
? 'extend' | 'duplicate'
: never
type Foldable1Methods<F extends URIS, I, A> = I extends Foldable1<F>
? 'reduce' | 'foldMap' | 'reduceRight'
: never
type FoldableWithIndex1Methods<F extends URIS, I, A> = I extends FoldableWithIndex1<F, infer Ix>
? 'reduceWithIndex' | 'foldMapWithIndex' | 'reduceRightWithIndex'
: never
type Alt1Methods<F extends URIS, I, A> = I extends Alt1<F>
? 'alt'
: never
type Compactable1Methods<F extends URIS, I> = I extends Compactable1<F>
? 'compact' | 'separate'
: never
type Filterable1Methods<F extends URIS, I, A> = I extends Filterable1<F>
? 'filter' | 'filterMap' | 'partition' | 'partitionMap'
: never
type FilterableWithIndex1Methods<F extends URIS, I, A> = I extends FilterableWithIndex1<F, infer Ix>
? 'filterWithIndex' | 'filterMapWithIndex' | 'partitionWithIndex' | 'partitionMapWithIndex'
: never
/**
* @since 2.0.0
*/
export interface Fluent1Defs<F extends URIS, I, A> {
readonly I: I
readonly value: Type<F, A>
show(this: Fluent1<F, Show<Type<F, A>>, A>): string
equals(this: Fluent1<F, Eq<Type<F, A>>, A>, that: Type<F, A>): boolean
compare(this: Fluent1<F, Ord<Type<F, A>>, A>, that: Type<F, A>): Ordering
concat(this: Fluent1<F, Magma<Type<F, A>>, A>, that: Type<F, A>): Type<F, A>
map<B>(this: Fluent1<F, Functor1<F>, A>, f: (a: A) => B): Fluent1<F, I, B>
mapWithIndex<Ix, B>(this: Fluent1<F, FunctorWithIndex1<F, Ix>, A>, f: (i: Ix, a: A) => B): Fluent1<F, I, B>
ap<B>(this: Fluent1<F, Apply1<F>, A>, fab: Type<F, (a: A) => B>): Fluent1<F, I, B>
apFirst<B>(this: Fluent1<F, Apply1<F>, A>, that: Type<F, B>): Fluent1<F, I, A>
apSecond<B>(this: Fluent1<F, Apply1<F>, A>, that: Type<F, B>): Fluent1<F, I, B>
chain<B>(this: Fluent1<F, Chain1<F>, A>, f: (a: A) => Type<F, B>): Fluent1<F, I, B>
flatten<A>(this: Fluent1<F, Chain1<F>, Type<F, A>>): Fluent1<F, I, A>
extend<B>(this: Fluent1<F, Extend1<F>, A>, f: (fa: Type<F, A>) => B): Fluent1<F, I, B>
duplicate(this: Fluent1<F, Extend1<F>, A>): Fluent1<F, I, Type<F, A>>
reduce<B>(this: Fluent1<F, Foldable1<F>, A>, b: B, f: (b: B, a: A) => B): B
foldMap<M>(this: Fluent1<F, Foldable1<F>, A>, M: Monoid<M>): (f: (a: A) => M) => M
reduceRight<B>(this: Fluent1<F, Foldable1<F>, A>, b: B, f: (a: A, b: B) => B): B
reduceWithIndex<Ix, B>(this: Fluent1<F, FoldableWithIndex1<F, Ix>, A>, b: B, f: (i: Ix, b: B, a: A) => B): B
foldMapWithIndex<Ix, M>(this: Fluent1<F, FoldableWithIndex1<F, Ix>, A>, M: Monoid<M>): (f: (i: Ix, a: A) => M) => M
reduceRightWithIndex<Ix, B>(this: Fluent1<F, FoldableWithIndex1<F, Ix>, A>, b: B, f: (i: Ix, a: A, b: B) => B): B
alt(this: Fluent1<F, Alt1<F>, A>, that: () => Type<F, A>): Fluent1<F, I, A>
compact<A>(this: Fluent1<F, Compactable1<F>, Option<A>>): Fluent1<F, I, A>
separate<A, B>(this: Fluent1<F, Compactable1<F>, Either<A, B>>): Separated<Type<F, A>, Type<F, B>>
filter<B extends A>(this: Fluent1<F, Filterable1<F>, A>, refinement: Refinement<A, B>): Fluent1<F, I, B>
filter(this: Fluent1<F, Filterable1<F>, A>, predicate: Predicate<A>): Fluent1<F, I, A>
filterMap<B>(this: Fluent1<F, Filterable1<F>, A>, f: (a: A) => Option<B>): Fluent1<F, I, B>
partition<B extends A>(
this: Fluent1<F, Filterable1<F>, A>,
refinement: Refinement<A, B>
): Separated<Type<F, A>, Type<F, B>>
partition(this: Fluent1<F, Filterable1<F>, A>, predicate: Predicate<A>): Separated<Type<F, A>, Type<F, A>>
partitionMap<RL, RR>(
this: Fluent1<F, Filterable1<F>, A>,
f: (a: A) => Either<RL, RR>
): Separated<Type<F, RL>, Type<F, RR>>
filterWithIndex<Ix>(this: Fluent1<F, FilterableWithIndex1<F, Ix>, A>, p: (i: Ix, a: A) => boolean): Fluent1<F, I, A>
filterMapWithIndex<Ix, B>(
this: Fluent1<F, FilterableWithIndex1<F, Ix>, A>,
f: (i: Ix, a: A) => Option<B>
): Fluent1<F, I, B>
partitionWithIndex<Ix>(
this: Fluent1<F, FilterableWithIndex1<F, Ix>, A>,
p: (i: Ix, a: A) => boolean
): Separated<Type<F, A>, Type<F, A>>
partitionMapWithIndex<Ix, RL, RR>(
this: Fluent1<F, FilterableWithIndex1<F, Ix>, A>,
f: (i: Ix, a: A) => Either<RL, RR>
): Separated<Type<F, RL>, Type<F, RR>>
}
type Fluent1<F extends URIS, I, A> = Pick<Fluent1Defs<F, I, A>, Fluent1Keys<F, I, A>>
export type Fluent1Keys<F extends URIS, I, A> = 'value' | Show1Methods<F, I> |
Eq1Methods<F, I, A> |
Ord1Methods<F, I, A> |
Magma1Methods<F, I, A> |
Functor1Methods<F, I, A> |
FunctorWithIndex1Methods<F, I, A> |
Apply1Methods<F, I, A> |
Chain1Methods<F, I, A> |
Extend1Methods<F, I, A> |
Foldable1Methods<F, I, A> |
FoldableWithIndex1Methods<F, I, A> |
Alt1Methods<F, I, A> |
Compactable1Methods<F, I> |
Filterable1Methods<F, I, A> |
FilterableWithIndex1Methods<F, I, A>
type ShowMethods<F, I> = I extends Show<HKT<F, any>> ? 'show' : never
type EqMethods<F, I, A> = I extends Eq<HKT<F, A>> ? 'equals' : never
type OrdMethods<F, I, A> = I extends Ord<HKT<F, A>> ? 'compare' : never
type MagmaMethods<F, I, A> = I extends Magma<HKT<F, A>> ? 'concat' : never
type FunctorMethods<F, I, A> = I extends Functor<F> ? 'map' : never
type FunctorWithIndexMethods<F, I, A> = I extends FunctorWithIndex<F, any>
? 'mapWithIndex'
: never
type ApplyMethods<F, I, A> = I extends Apply<F>
? 'ap' | 'apFirst' | 'apSecond'
: never
type ChainMethods<F, I, A> = I extends Chain<F>
? 'chain' | 'flatten'
: never
type ExtendMethods<F, I, A> = I extends Extend<F>
? 'extend' | 'duplicate'
: never
type FoldableMethods<F, I, A> = I extends Foldable<F>
? 'reduce' | 'foldMap' | 'reduceRight'
: never
type FoldableWithIndexMethods<F, I, A> = I extends FoldableWithIndex<F, infer Ix>
? 'reduceWithIndex' | 'foldMapWithIndex' | 'reduceRightWithIndex'
: never
type AltMethods<F, I, A> = I extends Alt<F>
? 'alt'
: never
type CompactableMethods<F, I> = I extends Compactable<F>
? 'compact' | 'separate'
: never
type FilterableMethods<F, I, A> = I extends Filterable<F>
? 'filter' | 'filterMap' | 'partition' | 'partitionMap'
: never
type FilterableWithIndexMethods<F, I, A> = I extends FilterableWithIndex<F, infer Ix>
? 'filterWithIndex' | 'filterMapWithIndex' | 'partitionWithIndex' | 'partitionMapWithIndex'
: never
export type FluentKeys<F, I, A> = 'value' | ShowMethods<F, I> |
EqMethods<F, I, A> |
OrdMethods<F, I, A> |
MagmaMethods<F, I, A> |
FunctorMethods<F, I, A> |
FunctorWithIndexMethods<F, I, A> |
ApplyMethods<F, I, A> |
ChainMethods<F, I, A> |
ExtendMethods<F, I, A> |
FoldableMethods<F, I, A> |
FoldableWithIndexMethods<F, I, A> |
AltMethods<F, I, A> |
CompactableMethods<F, I> |
FilterableMethods<F, I, A> |
FilterableWithIndexMethods<F, I, A>
class Wrapper<F, I, A> {
constructor(private I: I, readonly value: HKT<F, A>) {}
}
/**
* @since 2.0.0
*/
export function fluent<F extends URIS2, I, L>(I: { URI: F; _L: L } & I): <A>(fa: Type2<F, L, A>) => Fluent2<F, I, L, A>
export function fluent<F extends URIS2, I>(I: { URI: F } & I): <L, A>(fa: Type2<F, L, A>) => Fluent2<F, I, L, A>
export function fluent<F extends URIS, I>(I: { URI: F } & I): <A>(fa: Type<F, A>) => Fluent1<F, I, A>
export function fluent<F, I>(I: { URI: F } & I): <A>(fa: HKT<F, A>) => Fluent<F, I, A>
export function fluent<F, I>(I: { URI: F } & I): <A>(fa: HKT<F, A>) => any {
return fa => new Wrapper(I, fa)
}
// SAMPLE
const wrapO = fluent(option)
const wrapE = fluent(either)
const a = wrapO(some("Mattia")).map(s => s.length)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment