Skip to content

Instantly share code, notes, and snippets.

@bond15
Created February 20, 2021 22:48
Show Gist options
  • Save bond15/8d82f26dd6a5f0d3ef383828b3e32479 to your computer and use it in GitHub Desktop.
Save bond15/8d82f26dd6a5f0d3ef383828b3e32479 to your computer and use it in GitHub Desktop.
Merge Sort Hylomorphism
module Test where
import Control.Arrow((>>>))
type Algebra f a = f a -> a
type CoAlgebra f a = a -> f a
newtype Fix f = In { out :: (f (Fix f)) }
data TreeF a r = Empty | Leaf a | Node r r
instance Functor (TreeF a) where
fmap f Empty = Empty
fmap f (Leaf x) = Leaf x
fmap f (Node l r) = Node (f l) (f r)
type Tree a = Fix (TreeF a)
merge :: Ord a => [a] -> [a] -> [a]
merge [] m = m
merge n [] = n
merge (x:xs) (y:ys) | x <= y = x : merge xs (y:ys)
merge (x:xs) (y:ys) = y : merge (x:xs) ys
split :: CoAlgebra (TreeF a) [a]
split [] = Empty
split [x] = Leaf x
split xs = Node l r where
(l, r) = splitAt (length xs `div` 2) xs
combine :: Ord a => Algebra (TreeF a) [a]
combine Empty = []
combine (Leaf x) = [x]
combine (Node l r) = merge l r
hylo :: Functor f => Algebra f b -> CoAlgebra f a -> a -> b
hylo f g = g >>> fmap (hylo f g) >>> f
mergeSort :: Ord a => [a] -> [a]
mergeSort = hylo combine split
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment