Created
March 2, 2021 07:33
-
-
Save damhiya/95a0eced4ea8855fdb1924454ba3e2b3 to your computer and use it in GitHub Desktop.
initial algebra
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE StandaloneDeriving #-} | |
{-# LANGUAGE DeriveFunctor #-} | |
{-# LANGUAGE MultiParamTypeClasses #-} | |
{-# LANGUAGE FunctionalDependencies #-} | |
{-# LANGUAGE PatternSynonyms #-} | |
{-# LANGUAGE ViewPatterns #-} | |
{-# LANGUAGE LambdaCase #-} | |
module Fibonacci where | |
import Prelude hiding (Maybe(..), (+), fst, snd) | |
class Functor f => InitialAlgebra f a | a -> f where | |
initial :: f a -> a | |
terminal :: a -> f a | |
cata :: InitialAlgebra f a => (f b -> b) -> a -> b | |
cata f = f . fmap (cata f) . terminal | |
data Product a b = Product a b deriving Show | |
data CoProduct a b = CoFst a | CoSnd b deriving Show | |
data Terminal = Terminal deriving Show | |
newtype Maybe a = Maybe (CoProduct Terminal a) deriving (Functor, Show) | |
newtype Mu f = Mu (f (Mu f)) | |
newtype Nat = Nat (Mu Maybe) | |
deriving instance Functor (CoProduct a) | |
pattern Nothing :: Maybe a | |
pattern Nothing = Maybe (CoFst Terminal) | |
pattern Just :: a -> Maybe a | |
pattern Just x = Maybe (CoSnd x) | |
instance InitialAlgebra Maybe Nat where | |
initial Nothing = Nat (Mu Nothing) | |
initial (Just (Nat n')) = Nat (Mu (Just n')) | |
terminal (Nat (Mu Nothing)) = Nothing | |
terminal (Nat (Mu (Just n'))) = Just (Nat n') | |
pattern Z :: Nat | |
pattern Z = Nat (Mu Nothing) | |
pattern S :: Nat -> Nat | |
pattern S n <- (terminal -> Just n) | |
where | |
S = initial . Just | |
instance Show Nat where | |
show n = flip cata n $ \case | |
Nothing -> "Z" | |
Just m -> "S " ++ m | |
fst :: Product a b -> a | |
fst (Product x y) = x | |
snd :: Product a b -> b | |
snd (Product x y) = y | |
(+) :: Nat -> Nat -> Nat | |
m + n = flip cata m $ \case | |
Nothing -> n | |
Just m -> S m | |
fib :: Nat -> Nat | |
fib n = fst $ flip cata n $ \case | |
Nothing -> Product Z (S Z) | |
Just (Product x y) -> Product y (x+y) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment