Skip to content

Instantly share code, notes, and snippets.

View robrix's full-sized avatar
🌊
every dot and stroke I paint will be alive

Rob Rix robrix

🌊
every dot and stroke I paint will be alive
View GitHub Profile
@robrix
robrix / Main.hs
Created July 16, 2016 18:30
Recursive/Corecursive over F
{-# LANGUAGE DeriveFoldable, DeriveFunctor, FlexibleContexts, KindSignatures, RankNTypes, TypeFamilies #-}
module Main where
import Data.Bifunctor
newtype F f a = F { runF :: forall r. (a -> r) -> (f r -> r) -> r }
wrap :: Functor f => f (F f a) -> F f a
wrap f = F (\ p i -> i (fmap (\ (F r) -> r p i) f))
@robrix
robrix / FieldSet.hs
Created June 2, 2016 23:06
Extensible field sets, inspired by @aaronlevin’s extensible effects in the Van Laarhoven free monad: http://aaronlevin.ca/post/136494428283/extensible-effects-in-the-van-laarhoven-free-monad
{-# LANGUAGE DataKinds, FlexibleContexts, FlexibleInstances, GADTs, MultiParamTypeClasses, PolyKinds, TypeOperators #-}
module FieldSet where
infix 9 :=>
-- | We can probably replace this with a wrapper around `Tagged`.
newtype a :=> b = (:=>) b
deriving (Eq, Show)
-- | “Smart” (actually quite dumb) constructor for the tagged type above for convenience
field :: b -> a :=> b
@robrix
robrix / 1. RFunctor.hs
Last active June 4, 2016 19:01
Recursive functors with some fiddling for type parameter order
-- Old friends.
newtype Fix f = Fix { unFix :: f (Fix f) }
data Free f a = Free (f (Free f a)) | Pure a
data Cofree f a = a :< f (Cofree f a)
-- A recursive functor. We can’t define a Functor instance for e.g. `Fix` because:
-- 1. Its type parameter is of kind (* -> *). Maybe PolyKinds could hack around this, I’ve not tried.
-- 2. Following from that, its type parameter is applied to `Fix f` itself, and thus `(f (Fix f) -> g (Fix g)) -> Fix f -> Fix g` would probably be a mistake too; we want to ensure that `Fix` recursively maps its parameter functor into the new type, and not leave that map the responsibility of the function argument.
class RFunctor f
where rmap :: Functor a => (a (f b) -> b (f b)) -> f a -> f b
@robrix
robrix / Hammer.hs
Last active March 6, 2016 01:43
Parsing with Derivatives, via GADTs
data Parser a where
Cat :: Parser a -> Parser b -> Parser (a, b)
Alt :: Parser a -> Parser b -> Parser (Either a b)
Rep :: Parser a -> Parser [a]
Map :: Parser a -> (a -> b) -> Parser b
Bnd :: Parser a -> (a -> Parser b) -> Parser b
Lit :: Char -> Parser Char
Ret :: [a] -> Parser a
Nul :: Parser a
Eps :: Parser a
@robrix
robrix / init.js
Last active May 8, 2018 13:41
select-outside-brackets and select-scope commands, built using Bracket Matcher’s select-inside-brackets.
'use babel';
import {Range} from 'atom';
atom.commands.add('atom-text-editor', 'editor:select-outside-brackets', function () {
const editor = atom.workspace.getActiveTextEditor();
const initial = editor && editor.getSelectedBufferRange().freeze();
atom.commands.dispatch(editor.element, 'bracket-matcher:select-inside-brackets');
@robrix
robrix / apomorphisms.hs
Created March 5, 2015 02:32
Apomorphisms in Haskell
newtype Term f = In { out :: f (Term f) }
-- The trivial one
type RCoalgebra1 f a = a -> f (Either (Term f) a)
apo1 :: Functor f => RCoalgebra1 f a -> a -> Term f
apo1 f = In . (fmap fanin) . f
where fanin = either id (apo1 f)
@robrix
robrix / 1.md
Last active August 29, 2015 14:15
The sum is more than the hole of its parts
a b a && b
👎 👎 👎
👍 👎 👎
👎 👍 👎
👍 👍 👍
@robrix
robrix / &&-truth-table.md
Created February 17, 2015 02:59
The truth table for logical conjunction (&&)
a b a && b
👎 👎 👎
👍 👎 👎
👎 👍 👎
👍 👍 👍
@robrix
robrix / parseNull.md
Last active August 29, 2015 14:03
Convergence of parseNull in the derivative of parser combinators

Interpreting parseNull as the least fixed point of the parse null equations, ascending from ⊥ = {}

Given S → ϵ↓{x} ∪ S,

The zeroth iteration is :

parseNull⁰(S) = ⊥ = {}

The first is computed:

@robrix
robrix / δ.md
Last active August 29, 2015 14:03
Convergence of nullability in the derivative of parser combinators

Interpreting δ as the least fixed point of the nullability equations, ascending from ⊥ = false.

Given S → ϵ ∪ S,

The zeroth iteration is :

δ⁰(S) = ⊥ = false

The first is computed: