Skip to content

Instantly share code, notes, and snippets.

View masaeedu's full-sized avatar

Asad Saeeduddin masaeedu

  • Montreal, QC, Canada
View GitHub Profile
@masaeedu
masaeedu / nanoparsec.js
Last active June 30, 2025 18:36
Monadic parser combinators in JS
require("@babel/polyfill");
const {
adt,
_,
fail,
Maybe,
Fn,
Arr,
implement,
Chain,
@masaeedu
masaeedu / pleasetypecheckthis.js
Last active August 28, 2018 15:33
What I want from a typechecker
// :: type Eq e = { eq: e -> e -> Bool }
// :: type Semigroup s = { append: s -> s -> s }
// :: type Monoid m =
// :: (Semigroup m)
// :: & { empty: m }
// :: type Functor f = { map: (a -> b) -> (f a -> f b) }
@masaeedu
masaeedu / typemonoids.hs
Last active September 12, 2018 22:31
Folding type level lists using type level monoids
{-# LANGUAGE PolyKinds, DataKinds, TypeFamilies, TypeOperators, EmptyDataDecls, GADTs #-}
import Data.Proxy
import Data.Void
import Unsafe.Coerce
type family Foldr (append :: a -> b -> b) (zero :: b) fa :: b where
Foldr append zero '[] = zero;
Foldr append zero (x ': xs) = append x (Foldr append zero xs)
@masaeedu
masaeedu / adt.js
Last active November 5, 2018 18:32
A little library for ADTs in JS
const uncurry = f => args => args.reduce((p, c) => p(c), f)
const curry = n => f => {
const rec = a => acc => (a === 0 ? f(acc) : x => rec(a - 1)([...acc, x]))
return rec(n)([])
}
const mapWithKey = f => o =>
Object.keys(o).reduce((p, k) => ({ ...p, [k]: f(k)(o[k]) }), {})
@masaeedu
masaeedu / monoidal_functor.md
Created September 28, 2018 07:45
Monoidal functor

An applicative functor is a monoidal functor. What is a monoidal functor?

A monoidal functor is a functor between two monoidal categories that is roughly a monoid homomorphism (f (x <> y) = f x <> f y, f mempty = mempty) wrt their respective monoids.

But what are monoidal categories? They're categories equipped respectively with a "product" bifunctor and an "identity" object (subject to laws that are the rough translation of the monoid laws, which i will handwave).

Take Hask (types as objects, functions as morphisms) for example. Hask can be interpreted as a monoidal category if you take the bifunctor (,) as the product and () as the unit. This is more or less the "free monoid" of our monoidal category, because we're just taking the empty list of types as empty and concatenation of two types as append.

Now think of some applicative functor you know (e.g. Maybe). TBasically what it means for this functor to be monoidal is for the result of Maybe Hask to also be a monoidal category (in this c

@masaeedu
masaeedu / indexed_containers.hs
Created October 10, 2018 01:54
Zippability via isomorphism to functions of known domain
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE DeriveFunctor #-}
@masaeedu
masaeedu / recursion_schemes.js
Last active April 3, 2019 01:53
Recursion schemes for JS
// Consider a type consisting of either no values or two values (of distinct types)
// :: type TwoOrNone a b =
// :: { label: 'nil', values: () }
// :: | { label: 'cons', values: (a, b) }
// For convenience, we can write some constructors for values of this type,
// and a "destructor" to help us tell the different cases apart
// :: TwoOrNone a b
@masaeedu
masaeedu / typeofmatch.hs
Last active February 11, 2019 04:02
Trying to formalize the type of first class pattern matching in JS
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeInType #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
@masaeedu
masaeedu / automonad.js
Last active April 15, 2019 14:10
Automatic monad stack construction using pointed functors on the category of monads
const { mdo } = require("@masaeedu/do");
const {
Obj,
Fn,
Fnctr,
ReaderT,
Reader,
StateT,
State
} = require("@masaeedu/fp");
// Utils
const range = n => [...Array(n).keys()];
const add = ([x0, y0]) => ([x1, y1]) => [x0 + x1, y0 + y1];
const rotate = θ => ([x, y]) => [
Math.round(x * Math.cos(θ) - y * Math.sin(θ)),
Math.round(x * Math.sin(θ) + y * Math.cos(θ))
];
const map = f => g =>
function*() {
for (const v of g()) {