Skip to content

Instantly share code, notes, and snippets.

@Lucifier129
Created June 30, 2018 01:27
Show Gist options
  • Save Lucifier129/1172cbefce49205e0391be2c69aa5921 to your computer and use it in GitHub Desktop.
Save Lucifier129/1172cbefce49205e0391be2c69aa5921 to your computer and use it in GitHub Desktop.
var noop = () => {}
var compose = (f1, f2) => (...args) => f1(f2(...args))
var range = (start, end) => {
let n = start
let f = (next, complete) => {
if (n <= end) {
next(n++)
f(next, complete)
} else {
complete()
}
}
return f
}
var map = (source, f) => (next, complete) => source(value => next(f(value)), complete)
var reverse = source => {
let f
return (next, complete) => {
let composeNext = value => {
let feedValue = () => next(value)
f = compose(
f,
feedValue
)
}
f = complete
source(composeNext, () => f())
}
}
var foreach = (source, f) => source(f, noop)
var numbers = range(1, 10)
numbers = map(numbers, function(n) {
return n * n
})
numbers = reverse(numbers)
foreach(numbers, console.log)
@Lucifier129
Copy link
Author

codata in typescript

interface ListVisitor<T, TT> {
  unit: (value: T) => TT;
  cons: (a: TT, b: TT) => TT;
}

interface List<T> {
  <TT>(visitor: ListVisitor<T, TT>): TT;
}

const unit = <T>(value: T): List<T> => {
  return (visitor) => visitor.unit(value);
};

const cons = <T>(left: List<T>, right: List<T>): List<T> => {
  return (visitor) => {
    return visitor.cons(left(visitor), right(visitor));
  };
};

const range = (start: number, end: number): List<number> => {
  if (start === end) return unit(end);
  return cons(unit(start), range(start + 1, end));
};

interface MapFunction<T, TT> {
  (a: T): TT;
}

const map = <T, TT>(f: MapFunction<T, TT>) => (list: List<T>): List<TT> => {
  return (visitor) => {
    return list({
      unit: (value) => visitor.unit(f(value)),
      cons: (a, b) => visitor.cons(a, b),
    });
  };
};

const reverse = <T>(list: List<T>): List<T> => {
  return list({
    unit: (value) => unit(value),
    cons: (a, b) => cons(b, a),
  });
};

const foreach = <T>(f: (a: T) => any) => (list: List<T>) => {
  list({
    unit: f,
    cons: () => {},
  });
};

interface UnaryFunction<T, TT> {
  (arg: T): TT;
}

function pipe<T, A>(a: T, f1: UnaryFunction<T, A>): UnaryFunction<T, A>;
function pipe<T, A, B>(
  a: T,
  f1: UnaryFunction<T, A>,
  f2: UnaryFunction<A, B>
): UnaryFunction<T, B>;
function pipe<T, A, B, C>(
  a: T,
  f1: UnaryFunction<T, A>,
  f2: UnaryFunction<A, B>,
  f3: UnaryFunction<B, C>
): UnaryFunction<T, C>;
function pipe<T, A, B, C>(
  a: T,
  f1: UnaryFunction<T, A>,
  f2: UnaryFunction<A, B>,
  f3: UnaryFunction<B, C>
): UnaryFunction<T, C>;
function pipe<T, A, B, C, D>(
  a: T,
  f1: UnaryFunction<T, A>,
  f2: UnaryFunction<A, B>,
  f3: UnaryFunction<B, C>,
  f4: UnaryFunction<C, D>
): UnaryFunction<T, D>;

function pipe(a: any, ...args: UnaryFunction<any, any>[]) {
  return args.reduce((a, f) => f(a), a);
}

pipe(
  range(1, 10),
  map((n) => n * n),
  reverse,
  foreach(console.log)
);

/* output:

   100
   81
   64
   49
   36
   25
   16
   9
   4
   1
*/

@fc01
Copy link

fc01 commented Aug 5, 2021

type List = (i: number) => number

const range = (a: number, b: number): List =>
    i => i === -6666 ? b - a + 1 : a + i

const map = (list: List, f: (n: number) => number): List =>
    i => i === -6666 ? list(-6666) : f(list(i))

const reverse = (list: List): List =>
    i => i === -6666 ? list(-6666) : list(list(-6666) - 1 - i)


const foreach = (list: List, f: (n: number) => void) => {
    for (let i = 0; i < list(-6666); i++)f(list(i))
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment