Skip to content

Instantly share code, notes, and snippets.

View parsonsmatt's full-sized avatar

Matt von Hagen (Parsons) parsonsmatt

View GitHub Profile
@parsonsmatt
parsonsmatt / prismatic.hs
Created June 5, 2018 20:49
I figured out a nice way to pluck exceptions out of a constraint!
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PartialTypeSignatures #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
@parsonsmatt
parsonsmatt / mbc.hs
Created February 21, 2020 18:54
Compatibility function to make MonadUnliftIO and MonadBaseControl IO work together
{-
Oh no! You're lost in a twisty maze of IO lifting and unlifting, and you've come to
an impossible fork: you're currently in some monad that is `MonadBaseControl IO m`,
but you need to call a function in `MonadUnliftIO`. AND you need to call functions
in your original monad transformer, too!
We can make this work, but it's a bit hairy.
MonadUnliftIO is a strictly less powerful type class than `MonadBaseControl IO`, so
@parsonsmatt
parsonsmatt / skolem.hs
Created February 7, 2020 21:32
What's goin on with my skolems
-- This reproduction can be played with using `ghcid --allow-eval`
{-# language RankNTypes #-}
import Control.Monad.ST
newtype IdT m a = IdT { unIdT :: m a }
-- $> :set -XRankNTypes
--
@parsonsmatt
parsonsmatt / drf.hs
Last active July 30, 2019 14:49
I'm upset
{-# language DuplicateRecordFields, TypeApplications #-}
module DuplicateRecordFields where
data User = User { name :: String }
data Dog = Dog { name :: String }
-- Works
nameAlias :: User -> String
nameAlias = name
{-# LANGUAGE TypeApplications, GADTs, FlexibleInstances, OverloadedLists #-}
module History where
import Lib
import Control.Monad (join)
import qualified Data.Map as Map
import Data.Map (Map)
import qualified Data.List.NonEmpty as NEL
import Data.List.NonEmpty (NonEmpty(..))
-- We're modeling the following Haskell datatype:
--
-- data Animal = Cat Name Age | Dog Name OwnerId
--
-- We're going to factor the common 'Name' field into the animal table.
--
-- The data that is specific for each field will go on a table with that field.
-- First we create the animal_type.
CREATE TYPE animal_type AS ('cat', 'dog');
{-# LANGUAGE DeriveFunctor #-}
module SetIsNotAFunctor where
import Data.Set (Set)
import qualified Data.Set as Set
-- | A type for annotating a value where equality and ordering only care
-- about the value.
data Ann ann a = Ann { annotation :: ann, value :: a }
-- First we create the animal_type.
CREATE TYPE animal_type AS ('cat', 'dog');
-- Then we create the animal table with a primary key consisting of an
-- auto-incremented integer and the animal type.
CREATE TABLE animal (
id SERIAL NOT NULL,
type animal_type NOT NULL,
PRIMARY KEY (id, type),
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, GeneralizedNewtypeDeriving, FlexibleContexts #-}
module Lib where
import Control.Monad.State
import Control.Monad.Writer
import Control.Monad.IO.Class
import Control.Monad.Reader
someFunc :: IO ()
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}
module Lib where
class C a b | a -> b
instance C () Int
class Foo a where
foo :: C a b => a -> b -> IO ()