Skip to content

Instantly share code, notes, and snippets.

View Willmo36's full-sized avatar

Max Willmott Willmo36

  • SkipTheDishes
  • Saskatoon
View GitHub Profile
@Willmo36
Willmo36 / Vector.hs
Last active October 4, 2018 18:26
Haskell Vector learnings
data Vec = Vec [Int]
deriving (Show, Eq)
instance Monoid Vec where
mempty = (Vec mempty)
mappend = vecAdd
vecAdd (Vec a) (Vec b) = Vec $ zipWith (+) a b
vecSubtract (Vec a) (Vec b) = Vec $ zipWith (-) a b
@Willmo36
Willmo36 / fp-ts-queue.ts
Last active August 3, 2018 10:54
fp-ts Monad, Foldable & Setoid Queue
//BatchedQueue implementation from Chirs Okasaki's "Purely Functional Data Structures"
import { fromNullable } from "fp-ts/lib/Either";
import { Foldable1 } from "fp-ts/lib/Foldable";
import { Monad1 } from "fp-ts/lib/Monad";
import { getArraySetoid, Setoid } from "fp-ts/lib/Setoid";
const URI = "Queue";
type URI = typeof URI;
@Willmo36
Willmo36 / queue.ts
Last active August 3, 2018 10:53
Simple implementation of BatchedQueue from "Purely Functional Data Structures"
//BatchedQueue implementation from Chirs Okasaki's "Purely Functional Data Structures"
class Queue<A> {
constructor(public readonly f: A[], public readonly t: A[]) {}
}
export const empty = new Queue([], []);
export const isEmpty = <A>(q: Queue<A>) => q.f.length === 0;
/**
@Willmo36
Willmo36 / Tree.findFirst.ts
Created July 4, 2018 08:33
Tree.findFirst via Alt instance of Option
export const findFirst = <A>(predicate: (a: A) => boolean) => (t: Tree<A>): Option<A> => {
const ff = findFirst(predicate);
return t.fold(
() => none,
(l, v, r) =>
ff(l)
.orElse(() => ff(r))
.orElse(() => (predicate(v) ? some(v) : none))
);
};
@Willmo36
Willmo36 / fp-ts-most.ts
Created June 29, 2018 16:31
fp-ts bindings for most.js (inspired by the rxjs bindings found in the main wiki)
import { Alternative1 } from "fp-ts/lib/Alternative";
import { Monad1 } from "fp-ts/lib/Monad";
import { Monoid } from "fp-ts/lib/Monoid";
import * as most from "most";
declare module "most" {
interface Stream<A> {
_URI: URI;
_A: A;
}
@Willmo36
Willmo36 / task-stream-apply.ts
Last active June 28, 2018 21:59
fp-ts & most applicative things
import { Apply1 } from "fp-ts/lib/Apply";
import { Type, URIS } from "fp-ts/lib/HKT";
import { Task, task } from "fp-ts/lib/Task";
import { Stream, zip } from "most";
import { append } from "ramda";
import { Applicative1 } from "fp-ts/lib/Applicative";
export const sequenceTaskArray = <T>(ts: Task<T>[]): Task<T[]> =>
ts.reduce((acc, t) => {
const y = t.map(x => (ts: T[]) => append(x, ts));
@Willmo36
Willmo36 / liftA2.ts
Created March 20, 2018 15:03
liftA2.ts
const liftA2 = <T, R>(f: (x: T) => (y: T) => R) => (x: Maybe<T>) => (y: Maybe<T>): Maybe<R> => y.ap(x.map(f));
@Willmo36
Willmo36 / sequnce.maybe.js
Created March 6, 2018 10:41
sequence.ts (Maybe only atm)
import { Maybe } from "monet";
/**
* Turns Maybe<T>[] into Maybe<T[]>
* This is basically Ramda's sequence; http://ramdajs.com/docs/#sequence
* But their types don't let us use it *angryface*
* @param xs List of maybes
*/
export function sequence<T>(xs: Maybe<T>[]): Maybe<T[]> {
return xs.reduce<Maybe<T[]>>((acc, x) => {
@Willmo36
Willmo36 / DeepMergeWith.ts
Created February 16, 2018 12:48
Typed deep merge with Ramda
type Primitive = string | number | boolean | Symbol | null | undefined;
const isObject = (x: any): x is Object => R.is(Object, x);
const isPrimitive = (x: any): x is Primitive => !isObject(x);
const deepMergeWith = <T>(fn: <U extends Primitive>(a: U, b: U) => U) => (a: T, b: T): T => {
//base case
if (isPrimitive(a) && isPrimitive(b)) {
return fn(a, b);
}
//inductive step
@Willmo36
Willmo36 / most_custom.ts
Created February 5, 2018 16:32
distinctUntilChange - TypeScript extend Most.js
import { Stream } from "most";
import * as R from "ramda";
declare module "most" {
interface Stream<A> {
distinctUntilChange<T>(seed: T): Stream<T>;
}
}
const pairs = <P, C>(prev: P, current: C) => ({ seed: current, value: [prev, current] });