UNPKG

telegram-mtproto

Version:
136 lines (120 loc) 3.35 kB
//@flow // import { Maybe } from 'folktale/maybe' import { Maybe } from 'apropos' import { ᐸMapᐳ, ᐸEmptyᐳ, λMap } from './index.h' import OnlyStatic from '../only-static' export class Tuple<+A, +B> implements λMap<'Tuple', B> { typeName: 'Tuple' +ᐸ1ᐳ: A +ᐸ2ᐳ: B constructor(a: *, b: *) { this.ᐸ1/*::; const aa */ = a this.ᐸ2/*::; const bb */ = b } fst(): A { return this.ᐸ1ᐳ } snd(): B { return this.ᐸ2ᐳ } bimap<Aʹ, Bʹ>(f: (a: A) => Aʹ, g: (b: B) => Bʹ): Tuple<Aʹ, Bʹ> { return new Tuple(f(this.ᐸ1ᐳ), g(this.ᐸ2ᐳ)) } map<Bʹ>(f: (b: B) => Bʹ): Tuple<A, Bʹ> { return new Tuple(this.ᐸ1ᐳ, f(this.ᐸ2ᐳ)) } curry<X>(f: (x: Tuple<A, B>) => X): X { return f(this) } uncurry<X>(f: (a: A, b: B) => X): X { return f(this.ᐸ1ᐳ, this.ᐸ2ᐳ) } extend<N>(f: (x: Tuple<A, B>) => N): Tuple<A, N> { return new Tuple(this.ᐸ1ᐳ, f(this)) } extract(): B { return this.ᐸ2ᐳ } foldl<X, Z>(f: (b: B, z: Z) => X, z: Z): X { return f(this.ᐸ2ᐳ, z) } foldr<X, Z>(f: (z: Z, b: B) => X, z: Z): X { return f(z, this.ᐸ2ᐳ) } foldMap<X>(f: (b: B) => X): X { return f(this.ᐸ2ᐳ) } equals<Aʹ, Bʹ>(tuple: Tuple<Aʹ, Bʹ>): boolean { return this.eqFirst(tuple) && this.eqSecond(tuple) } eqFirst<Aʹ, -Bʹ>(tuple: Tuple<Aʹ, Bʹ>): boolean { return eq(this.fst(), tuple.fst()) } eqSecond<-Aʹ, Bʹ>(tuple: Tuple<Aʹ, Bʹ>): boolean { return eq(this.snd(), tuple.snd()) } toValue() { return [this.ᐸ1ᐳ, this.ᐸ2ᐳ] } toJSON() { return this.toValue() } toString() { return `Tuple( ${String(this.ᐸ1ᐳ)}, ${String(this.ᐸ2ᐳ)} )` } static of<Aʹ, Bʹ>(a: Aʹ, b: Bʹ): Tuple<Aʹ, Bʹ> { return new Tuple(a, b) } } export class TupleT extends OnlyStatic { static fromArray<A, B>(list: [A, B][]): Array<Tuple<A, B>> { return list.map(([key, val]) => ofTuple(key, val)) } static of = ofTuple static traverseMaybe = traverseMaybe static snd = snd static fst = fst } function traverseMaybe<A, B>(tuple: Tuple<A, Maybe<B>>): Maybe<Tuple<A, B>> { const a = tuple.fst() const b = tuple.snd() return b.map(bVal => new Tuple(a, bVal)) } function snd<-A, B>(tuple: Tuple<A, B>): B { return tuple.snd() } function fst<A, -B>(tuple: Tuple<A, B>): A { return tuple.fst() } function eq(a, b): boolean { if (a === b) return true if (canCompare(a) && canCompare(b)) //$off return a.equals(b) && b.equals(a) return false } function ofTuple<Aʹ, Bʹ>(a: Aʹ, b: Bʹ): Tuple<Aʹ, Bʹ> { return new Tuple(a, b) } const typeID = 'zero-bias/Tuple@1' export const MTuple: ( & ᐸMapᐳ<'Tuple'> & ᐸEmptyᐳ<'Tuple'> ) = { '@@type' : typeID, of : <A, B>([a, b]: [A, B]): Tuple<A, B> => new Tuple(a, b), 'fantasy-land/of' : <A, B>([a, b]: [A, B]): Tuple<A, B> => new Tuple(a, b), empty : (): Tuple<void, void> => new Tuple(void 0, void 0), 'fantasy-land/empty': (): Tuple<void, void> => new Tuple(void 0, void 0) } /*:: ; const dull = {} */ Object.assign(/*:: dull, */ Tuple, MTuple) function canCompare(x): boolean { return ( typeof x === 'object' && x != null && typeof x.equals === 'function' ) } export default Tuple