Skip to content

Instantly share code, notes, and snippets.

@luqui
luqui / opaque.hs
Last active May 23, 2020 08:09
Natural transformations never need to type switch
{-# LANGUAGE RankNTypes, TypeApplications #-}
-- We give a constructive proof that any natural transformation that uses
-- a type switch in its implementation can also be implemented without the type switch,
-- as long as the domain functor is finitely Traversable (and the argument can easily
-- be modified to drop the finiteness property).
-- We do this by providing a function `opaquify` which takes an n.t. which may do
-- type switches, and returns an equivalent n.t. which does not.
@luqui
luqui / opaque.mkd
Created May 23, 2020 04:32
Natural transformations must treat their arguments opaquely

We will give some strong evidence for the claim "natural transformations must treat their arguments opauely". This is the best I can come up with short of defining a lambda calculus with type-switch and showing that the type-switch can always be eliminated (which I suspect would be possible) but is too difficult. Instead, we show that the requirement that a function be a natural transformation is invariant under encodings -- that is, if you mangle the argument in whatever way you like, and unmangle the result, you get the same thing as if you didn't do any mangling.

Therefore, in order to a natural transformation t :: F a -> G a to make an "exception" for a type, it would have to make the same exception for all possible encodings of that type as well. In particular, one possible encoding is to encode each incoming a in F as a unique integer. The resulting integers in the result G value show us exactly

@luqui
luqui / foldl.hs
Last active December 27, 2019 04:00
Example of how to get intermediate results from a Fold
import qualified Control.Foldl as Foldl
average :: Foldl.Fold Double Double
average = (/) <$> Foldl.sum <*> Foldl.genericLength
-- This could have been done more easily with the Foldl.scan function, but
-- I wanted to demonstrate how to access the intermediate states manually.
averages :: [Double] -> [Double]
averages xs
| Foldl.Fold step s0 obs <- average
@luqui
luqui / higher_products.hs
Last active September 11, 2018 15:28
Higher-kinded products using "axiomatic types"
{-# OPTIONS -fdefer-type-errors #-}
{-# LANGUAGE DataKinds, PolyKinds, TypeFamilies, TypeOperators, RankNTypes, GADTs, TypeApplications, ScopedTypeVariables, UndecidableInstances, MultiParamTypeClasses, TypeInType, TypeSynonymInstances, FlexibleInstances, InstanceSigs, FlexibleContexts #-}
import Prelude hiding (id, (.))
import Control.Category
import Data.Kind (Type)
import Unsafe.Coerce
import Data.Type.Equality
type family (~>) :: k -> k -> Type
-- In an alternate universe of Haskell where this worked...
data (Num a) => Complex a = a :+ a
instance Functor Complex where
fmap f (x :+ y) = f x :+ f y
instance Monad Complex where
return x = x :+ 0
join ((a :+ b) :+ (c :+ d)) = (a - d) :+ (b + c)
@luqui
luqui / baseball.html
Last active February 27, 2017 02:54
HTML help for Luke J
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
h1 {
font-family:"Impact";
font-size: 48pt;
text-align: left;
text-indent: 48px;
color: #000;
@luqui
luqui / dragon.hs
Created December 16, 2016 16:50
dragon curve experiments
{-# LANGUAGE RankNTypes, GADTs, ConstraintKinds, ScopedTypeVariables, DeriveFunctor #-}
import Data.Monoid
import Data.Foldable (toList)
import Data.Constraint (Dict(..))
import qualified Data.DList as DList
import qualified Data.Sequence as Seq
class (Functor f) => DragonList f where
singleton :: a -> f a
@luqui
luqui / table.md
Last active August 29, 2015 14:13

Really? <table> isn't available in markdown?

4
1 2
3
@luqui
luqui / howtowrite.hs
Last active August 29, 2015 13:58
How to write this book
import Data.List (intercalate)
write :: String -> String
write = intercalate ". " . map (\word -> "Write " ++ show word) . words
howToWrite :: String
howToWrite = "How to write this book: " ++ write howToWrite
{-
>>> putStrLn $ take 1000 howToWrite
data Set : Type where
Comp : (Set -> Type) -> Set
elt : Set -> Set -> Type
elt (Comp f) = f
W : Set
W = Comp (\A => Not (A `elt` A))
Russell : Type