Created
July 27, 2017 13:23
-
-
Save holoed/3120ea34bcfe44801a418dab95ab9d01 to your computer and use it in GitHub Desktop.
A duality of sorts
This file contains hidden or 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 UndecidableInstances #-} | |
{-# LANGUAGE DeriveFunctor #-} | |
module Main where | |
-- Fix point | |
fix :: ((a -> b) -> (a -> b)) -> (a -> b) | |
fix f = f (fix f) | |
newtype Fix f = In { out :: f (Fix f) } | |
instance Show (f (Fix f)) => Show (Fix f) where | |
show (In f) = "(" ++ show f ++ ")" | |
-- Recursion Schemes | |
cata :: Functor f => (f a -> a) -> (Fix f -> a) -> (Fix f -> a) | |
cata psi f = psi . fmap f . out | |
cataRec :: Functor f => (f a -> a) -> (Fix f -> a) | |
cataRec psi = fix (cata psi) | |
ana :: Functor f => (a -> f a) -> (a -> Fix f) -> (a -> Fix f) | |
ana psi f = In . fmap f . psi | |
anaRec :: Functor f => (a -> f a) -> (a -> Fix f) | |
anaRec psi = fix (ana psi) | |
-- List | |
data ListF a b = Empty | Cons a b deriving (Functor, Show) | |
type List a = Fix (ListF a) | |
fromListAlg :: [a] -> ListF a [a] | |
fromListAlg [] = Empty | |
fromListAlg (x:xs) = Cons x xs | |
fromList :: [a] -> List a | |
fromList = anaRec fromListAlg | |
toListAlg :: ListF a [a] -> [a] | |
toListAlg Empty = [] | |
toListAlg (Cons x xs) = x:xs | |
toList :: List a -> [a] | |
toList = cataRec toListAlg | |
swap :: Ord a => ListF a (ListF a b) -> ListF a (ListF a b) | |
swap Empty = Empty | |
swap (Cons a Empty) = Cons a Empty | |
swap (Cons a (Cons b x)) | |
| a <= b = Cons a (Cons b x) | |
| otherwise = Cons b (Cons a x) | |
sortList :: Ord a => List a -> List a | |
sortList = anaRec (cataRec (fmap In . swap)) | |
sort :: Ord a => [a] -> [a] | |
sort = toList . sortList . fromList | |
main :: IO () | |
main = print $ sort [1,9,2,8,4,7,5,6,0,3] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment