Skip to content

Instantly share code, notes, and snippets.

View ChrisPenner's full-sized avatar
:bowtie:
Happily Hacking

Chris Penner ChrisPenner

:bowtie:
Happily Hacking
View GitHub Profile
@ChrisPenner
ChrisPenner / copy
Last active April 4, 2017 20:34
Copy-pasta commands
#!/bin/bash
# Use at your own risk :P
FOLDER="/tmp/copy-pasta"
if [ $# -lt 1 ]; then
cat << EOF
usage: copy <files>
EOF
exit 1
fi
@ChrisPenner
ChrisPenner / divisible-renderers.hs
Last active July 27, 2017 09:13
Splitting app state rendering into parts using Contravariant Divisible
-- Attempt splitting an 'App Renderer' into smaller renderers using the Contravariant Divisible class;
-- Didn't really work out great, seems better to just use simple contramaps to map each renderer into
-- a `Renderer AppState` and then use a monoid to fold them.
{-# language InstanceSigs #-}
module Main where
import Data.Foldable
import Data.Functor.Contravariant
import Data.Functor.Contravariant.Divisible
@ChrisPenner
ChrisPenner / Flux.hs
Created June 11, 2017 17:20
Fluctuation counting Monoid
-- | 'Flux' is a monoid which counts the number of times an element changes
-- values (according to its Eq instance)
-- This is useful for gaining associativity (and its associated performance improvements)
-- for tasks where you'd otherwise use `group` or `groupBy`
data Flux a = Flux
-- We keep track of the last value we saw on the left and right sides of the accumulated
-- sequence; `Nothing` is used in the identity case meaning no elements have yet
-- been encountered
{ sides :: Maybe (a, a)
-- We have a counter which increments each time we mappend another Flux who's
@ChrisPenner
ChrisPenner / CommandRing.hs
Last active June 19, 2017 04:23
Commands as a Ring
module CommandRing where
class (Monoid g) => Ring g where
identity :: g
identity = mempty
plus :: g -> g -> g
plus = mappend
invert :: g -> g
{-# language DeriveFunctor #-}
{-# language FlexibleInstances #-}
{-# language FlexibleContexts #-}
module Rasa.Ext.Views.Internal.CoTree where
import Data.List as L
class Monoid g => Group g where
identity :: g
identity = mempty
@ChrisPenner
ChrisPenner / Tape.lhs
Last active January 1, 2023 13:09
Building up Zippers from Distributive, Representable, and Cofree
We're going to take a look at an alternative way to define a Zipper Comonad
over a data type. Typically one would define a Zipper Comonad by defining a new
datatype which represents the Zipper; then implementing `duplicate` and
`extract` for it. `extract` is typically straightforward to write, but I've had
some serious trouble writing `duplicate` for some more complex data-types like
trees.
We're looking at a different way of building a zipper, The advantages of this
method are that we can build it up out of smaller instances piece by piece.
Each piece is a easier to write, and we also gain several utility functions
@ChrisPenner
ChrisPenner / LispParser.hs
Last active August 16, 2018 14:22
Lisp Parser in a tweet :)
module LispParser where
import Text.Megaparsec
import Text.Megaparsec.String
import Text.Megaparsec.Lexer hiding (space)
data E=L[E]|S String|N Integer deriving Show
e=(char '('*>(L<$>some e)<*char ')'<|>N<$>integer<|>S<$>some letterChar)<*space::Parser E
@ChrisPenner
ChrisPenner / Battleship.lhs
Last active September 10, 2023 03:12
Hit! You sunk my Adjunction!
Today we'll be looking into Kmett's
[adjunctions](http://hackage.haskell.org/package/adjunctions) library,
particularly the meat of the library in Data.Functor.Adjunction.
This post is a literate haskell file, which means you can load it right up in
ghci and play around with it! Like any good haskell file we need half a dozen
language pragmas and imports before we get started.
> {-# language DeriveFunctor #-}
> {-# language TypeFamilies #-}
{-# language DeriveFunctor #-}
{-# language TypeFamilies #-}
{-# language MultiParamTypeClasses #-}
{-# language FlexibleInstances #-}
module FreeForget where
import Data.Distributive
import Data.Functor.Rep
import Data.Functor.Adjunction
@ChrisPenner
ChrisPenner / RepresentableSorting.lhs
Last active July 26, 2017 02:53
Radix Sort and Trie Trees with Representable Functors
Looking at my recent posts it's clear I've been on a bit of a Representable
kick lately; turns out there's a lot of cool things you can do with it! We'll
be adding 'sorting' to that list of things today. Representable Functors bring
with them an intrinsic notion of sorting; not in the traditional 'ordered'
sense, but rather a sense of 'structural' sorting. Since every 'slot' in a
Representable Functor `r` can be uniquely identified by some `Rep r` we can
talk about sorting items into some named slot in `r`. If we like we can also
define `Ord (Rep r)` to get a total ordering over the slots, but it's not
required.