Skip to content

Instantly share code, notes, and snippets.

@LivewareIssue
LivewareIssue / Ships.hs
Created February 22, 2021 02:04
Reddit Typeclass Example
import Text.Printf (printf)
data Cartesian = Cartesian { x :: Double, y :: Double }
instance Show Cartesian where
show (Cartesian x y) = printf "{ x: %.2f, y: %.2f }" x y
class Show a => Coordinate a where
toCartesian :: a -> Cartesian
fromCartesian :: Cartesian -> a
@LivewareIssue
LivewareIssue / Permissions.hs
Created December 30, 2020 18:26
Permissions as a free lattice
data Term
= Role Role
| Permission Permission
deriving (Eq, Ord, Show)
data Role
= Admin
| User
deriving (Eq, Ord, Show)
@LivewareIssue
LivewareIssue / Data.Enumerable.hs
Last active September 13, 2020 00:50
Enums as isomorphisms with finite types
data Permission = Create | Read | Update | Delete
deriving (Eq, Enum, Show)
instance Enumerable Permission where
type Cardinality Permission = 4
main ∷ IO ()
main = do
let xs = insert Create None
print $ toList @Permission xs
@LivewareIssue
LivewareIssue / Data.Tuple.Extras.hs
Created August 17, 2020 01:55
Convenience functions for pairs
import Control.Arrow ((***), (&&&))
import Control.Monad (join)
duplicate ∷ a → (a, a)
duplicate = id &&& id
both ∷ (a → b) → (a, a) → (b, b)
both = join (***)
@LivewareIssue
LivewareIssue / IntegerSpiral.hs
Created June 10, 2020 23:33
Print the integers from 1..n in a spiral
{-# LANGUAGE UnicodeSyntax #-}
module IntegerSpiral where
import Data.Function ((&))
import Text.Printf (printf)
import Data.VectorSpace ((^+^), (^-^))
import Data.Map (Map)
import qualified Data.Map as Map
import Data.List (intersperse)
@LivewareIssue
LivewareIssue / MinimumSubstring.hs
Created May 23, 2020 19:32
Find the minimum-length substring in s that contains every character (including repeats) of t
import Data.Sequence (Seq, pattern (:<|), pattern (:|>))
import qualified Data.Sequence as Seq
import Data.MultiSet (MultiSet)
import qualified Data.MultiSet as MultiSet
import Data.List (unfoldr)
initialWindow ∷ s → [a] → Window s a
initialWindow s0 = (Window Seq.Empty s0) . Seq.fromList
data Window s a = Window (Seq a) s (Seq a)
@LivewareIssue
LivewareIssue / MatchingPairs.hs
Created May 21, 2020 22:00
Given two strings s and t of length N, find the maximum number of possible matching pairs in strings s and t after swapping exactly two characters within s.
import Data.List (tails, partition)
main = do
print $ maximumPairs "abcd" "adcb"
boundedMaximum least greatest [] = least
boundedMaximum least greatest (x:xs)
| x == greatest = x
| otherwise = boundedMaximum (max least x) greatest xs
@LivewareIssue
LivewareIssue / YearbookPassing.hs
Last active June 17, 2020 06:33
Yearbook-passing puzzle
import Data.Vector (Vector)
import qualified Data.Vector as Vector
import Data.Maybe (fromJust)
import Data.Map (Map)
import qualified Data.Map as Map
{- You're given a permutation of a set of n students, numbered from 1 to n (e.g. [1,5,3,2,4]).
To begin with, each student is holding their own yearbook. Each student, i, signs the notebook they're currently
holding before passing it to the student at index i. This repeats until every student has received their own yearbook
@LivewareIssue
LivewareIssue / RecursionSchemes.hs
Last active September 13, 2020 01:30
Simple recursion-schemes
main = do
n <- readLn
print $ fibonacci (n-1)
data NatF α = ZeroF | SuccF α
deriving Functor
fib :: Integer -> Integer
fib 0 = 0
fib 1 = 1
@LivewareIssue
LivewareIssue / Quicksort.hs
Created May 21, 2020 21:33
Quicksort via hylomorphism
data BinTreeF a b = Empty | Branch b a b
deriving Functor
type BinTree a = Fix (BinTreeF a)
divide :: Ord a => [a] -> BinTreeF a [a]
divide [] = Empty
divide (pivot:xs) = Branch lo pivot hi
where
(lo,hi) = partition (< pivot) xs