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 / Selectable.hs
Last active August 3, 2017 05:54
Selectable
{-# language DeriveFunctor #-}
{-# language DeriveFoldable #-}
{-# language GeneralizedNewtypeDeriving #-}
{-# language UndecidableInstances #-}
{-# language StandaloneDeriving #-}
module Data.Functor.Selectable where
import Control.Arrow ((&&&))
import Control.Comonad
import Data.Bifunctor
@ChrisPenner
ChrisPenner / TicTacToe.hs
Last active August 26, 2017 18:18
Type-safe game of TicTacToe
{-# language DeriveFunctor #-}
{-# language DataKinds #-}
{-# language GADTs #-}
{-# language ViewPatterns #-}
{-# language TypeFamilies #-}
module Prog where
import Data.Function ((&))
-- | Either X, O, or Nothing
@ChrisPenner
ChrisPenner / heyting-validation.js
Created August 23, 2017 14:32
Heyting Algebra Validation
const all = (...preds) => (obj) => preds.map(f => f(obj)).reduce((a, b) => a && b, true)
const any = (...preds) => (obj) => preds.map(f => f(obj)).reduce((a, b) => a || b, false)
const oneOf = (...preds) => (obj) => preds.map(f => f(obj)).reduce((a, b) => a ? !b : b, false)
const has = (prop) => (obj) => obj[prop] !== undefined
const not = (pred) => (obj) => !pred(obj)
const equals = (prop, val) => (obj) => obj[prop] === val
const implies = (f, g) => (obj) => !f(obj) || g(obj);
const validate = all(implies(has('selectedIndex'), equals('isOpen', true)))
@ChrisPenner
ChrisPenner / FreeMonadOptimization.hs
Last active August 24, 2017 02:18
Free Monads vs MTL regarding optimizations using AST transformations
{-# language DeriveFunctor #-}
{-# language GeneralizedNewtypeDeriving #-}
module FreeOpt where
import Control.Monad.Free
import Control.Monad.Trans
import System.Directory
-- | Define our Free Monad DSL
data FileF r =
@ChrisPenner
ChrisPenner / custom-state-handlers.purs
Last active October 30, 2017 02:25
Custom State Handlers
module Main where
import Prelude
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Console (CONSOLE, log)
import Data.Either (Either(..))
import Data.Monoid (class Monoid, mempty)
import Run (Run, extract, lift, on, peel, send)
import Run.State (STATE, State(..))
@ChrisPenner
ChrisPenner / README.md
Created June 3, 2018 00:31
Use Google Sheet as BigQuery Dataset

Generating BQ schema from google sheet header row

To generate a new schema:

  • Copy the ID header row from your google sheet

  • pbpaste | python make_schema.py

  • There's your BQ schema!

  • Add a new dataset to bigquery

  • Use your spreadsheet link as the file location

@ChrisPenner
ChrisPenner / update-monads.md
Created September 1, 2018 22:24
Update Monads

Today we're going to take a peek at the Update monad! It's a monad which was formalized and described in Update Monads: Cointerpreting Directed Containers by Danel Ahman and Tarmo Uustalu. Most folks probably haven't heard of it before, likely because most of what you'd use it for is well encompassed by the Reader, Writer, and State monads. The Update Monad can do everything that Reader, Writer, and State can do, but as a trade-off tends to be less efficient at each of those tasks. It's definitely still worth checking out though; not only is it interesting, there are a few things it handles quite elegantly that might be a bit awkward to do in other ways.

@ChrisPenner
ChrisPenner / matrix-search-comonad.hs
Last active November 12, 2018 20:47
Matrix path search using comonads
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE OverloadedLists #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module Lib where
@ChrisPenner
ChrisPenner / GenericMonoid.hs
Last active February 22, 2019 19:51
Derive Monoid for using Generics
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE DeriveGeneric #-}
module GenericMonoid where
import Data.Monoid
import Data.Maybe
@ChrisPenner
ChrisPenner / DynamicComonad.hs
Created April 5, 2019 20:22
Dynamic Programming Comonads using Recursion Schemes
import Data.Functor.Foldable
import Control.Comonad.Cofree as C
import Control.Comonad.Trans.Cofree as CF
cofreeDynExtend :: forall f a b.
Functor f
=> (CofreeF f a (C.Cofree f b) -> b)
-> C.Cofree f a
-> C.Cofree f b
cofreeDynExtend f = cata extract'