Skip to content

Instantly share code, notes, and snippets.

@tekerson
tekerson / exercism-community-solutions.user.js
Created August 30, 2018 14:47
Userscript to add a "Community Solutions" link to the mentor page on Exercism.io
// ==UserScript==
// @name Show Community Solutions
// @namespace tekerson.com
// @version 1.0.0
// @description Add a "Community Solutions" link to the mentor page on Exercism.io
// @match https://exercism.io/mentor/solutions/*
// @grant GM_openInTab
// @noframes
// @run-at document-end
// ==/UserScript==
@tekerson
tekerson / HigherKindedTypes.ts
Created December 13, 2017 22:58
Experiment with modelling Higher Kinded Types (HKTs) in TypeScript
interface HKT<F, A> {
__hkt: [F, A];
}
namespace FunctorNS {
export interface Functor<F, A> extends HKT<F, A> {
map<B>(f: (a: A) => B): Functor<F, B>;
}
export const map = <F, A, B>(
@tekerson
tekerson / 1.1.js
Created December 1, 2017 23:01
Advent of Code 2017 - JavaScript
const solve = (input) => input
.split('').map(v => parseInt(v, 10))
.reduce((acc, value, i, list) => {
const pair = list[(i + 1) % list.length]
return acc + (value === pair ? value : 0)
}, 0)
@tekerson
tekerson / NonEmpty.ts
Created November 30, 2017 22:44
Possible implementation of a non-empty collection in TypeScript
class NonEmpty<T> {
readonly head: T
protected tail: Array<T>
constructor(head: T, ...tail: T[]) {
this.head = head
this.tail = tail
}
static fromArray<U>(values: Array<U>): NonEmpty<U> | undefined {
if (values.length === 0) return undefined

Keybase proof

I hereby claim:

  • I am tekerson on github.
  • I am brenton (https://keybase.io/brenton) on keybase.
  • I have a public key ASC3ReVzC9x-LBWc51DRRX5uqVJ1immTtP-FpEWB0egoLwo

To claim this, I am signing this object:

-- Does not compile: different currencies
add (MkMoney "EUR" 1) (MkMoney "USD" 2)
@tekerson
tekerson / calculator-ast-alt.js
Last active March 16, 2017 08:35
With/without Intermediate Form (AST) comparison
const AST = {
Add: (left, right) => (cases) => cases['Add'](left, right),
Multiply: (left, right) => (cases) => cases['Multiply'](left, right),
Number: (value) => (cases) => cases['Number'](value)
}
const parse = (str) => {
const stack = []
str.split(' ').forEach(token => {
switch (token) {
const posLens = R.lensProp('positives')
const negLens = R.lensProp('negatives')
const positives = R.view(posLens)
const negatives = R.view(negLens)
const incrementPositiveCount = R.over(posLens, R.inc)
const incrementNegativeCount = R.over(negLens, R.inc)
const seenBoth = c => R.allPass([
const tmp = require('tmp')
/**
* Create a temporary directory and ensure that it is cleaned up after the handler completes
* @sig (tmpDir: String -> a) -> Promise a
*/
exports.withTempDirectory = (handler) => new Promise((resolve, reject) => {
tmp.dir({ unsafeCleanup: true }, (err, tmpDir, cleanup) => {
if (err) {
reject(err)
@tekerson
tekerson / pre-commit
Created August 7, 2015 02:29
Some pre-commit hooks that check for things that I shouldn't be committing
#!/bin/sh
if git rev-parse --verify HEAD >/dev/null 2>&1
then
against=HEAD
else
# Initial commit: diff against an empty tree object
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi