Skip to content

Instantly share code, notes, and snippets.

View robrix's full-sized avatar
🌊
every dot and stroke I paint will be alive

Rob Rix robrix

🌊
every dot and stroke I paint will be alive
View GitHub Profile
@robrix
robrix / FoldsAndUnfolds.hs
Created March 31, 2021 22:44
Recursion schemes over lists, in contrast with foldr/unfoldr
module FoldsAndUnfolds where
import Data.List -- for unfoldr
class Functor f => Recursive f t | t -> f where
project :: t -> f t
cata :: (f a -> a) -> t -> a
cata alg = go where go = alg . fmap go . project
@robrix
robrix / MuNu.hs
Created June 20, 2021 23:19
Least and greatest fixed-points in Haskell
newtype Mu f = Mu (forall r . (f r -> r) -> r)
foldMu :: (f a -> a) -> Mu f -> a
foldMu alg (Mu f) = f alg
unfoldMu :: Functor f => (a -> f a) -> a -> Mu f
unfoldMu coalg a = Mu $ \ alg -> refold alg coalg a
refoldMu :: Functor f => (f b -> b) -> (a -> f a) -> a -> b
refoldMu f g = foldMu f . unfoldMu g
@robrix
robrix / LC.hs
Created July 17, 2021 15:35
A catamorphism-based interpreter and an abstract machine for the untyped lambda calculus
type Name = String
-- first-order syntax
data Tm
= Var Name
| Abs Name Tm
| App Tm Tm
deriving (Eq, Ord, Show)
type Env = [(Name, Val)]
@robrix
robrix / MonadicFolds.hs
Created April 2, 2022 20:05
Monadic cata, ana, and hylo
newtype Fix f = In { out :: f (Fix f) }
cata :: Functor f => (f a -> a) -> (Fix f -> a)
cata alg = go where go = alg . fmap go . out
ana :: Functor f => (a -> f a) -> (a -> Fix f)
ana coalg = go where go = In . fmap go . coalg
hylo1 :: Functor f => (f b -> b) -> (a -> f a) -> (a -> b)
@robrix
robrix / Failover.hs
Last active June 26, 2022 12:27
A Failover effect, like Choose but with laws like Maybe's Alternative instance
import Control.Algebra
-- Failover effect
failover :: Has Failover sig m => m a -> m a -> m a
failover a b = send (Failover a b)
infixl 3 `failover`
data Failover m k where
@robrix
robrix / Ref.hs
Created July 23, 2022 14:20
Ref effect, bridged to State
data Ref ref (m :: K.Type -> K.Type) k where
NewRef :: a -> Ref ref m (ref a)
ReadRef :: ref a -> Ref ref m a
WriteRef :: ref a -> a -> Ref ref m ()
newRef :: Has (Ref ref) sig m => a -> m (ref a)
newRef a = send (NewRef a)
readRef :: Has (Ref ref) sig m => ref a -> m a
readRef ref = send (ReadRef ref)