Skip to content

Instantly share code, notes, and snippets.

@adamzaninovich
Created September 21, 2012 11:25
Show Gist options
  • Save adamzaninovich/3760961 to your computer and use it in GitHub Desktop.
Save adamzaninovich/3760961 to your computer and use it in GitHub Desktop.
Striving for combination in Haskell
-- Recursive definition of factorial
fact :: (Num a, Ord a) => a -> a
fact n
| n == 0 = 1
| otherwise = n * fact (n-1)
-- ----------------------------------------------------------------------
-- Improver
fact_improver :: (Int -> Int) -> Int -> Int
fact_improver = \f -> \n -> if n <= 1 then 1 else n * f (n-1)
-- Y-like fixed-point combinator
-- (Calculates the FIXPOINT of an improver function)
fix :: (a -> a) -> a
fix = \f -> f (fix f)
-- The fixpoint of the improver IS the factorial function
fact' :: Int -> Int
fact' = fix fact_improver
-- ----------------------------------------------------------------------
-- Actual Y Combinator requires defining recursive types
-- based off http://en.wikipedia.org/wiki/Fixed_point_combinator#Example_of_encoding_via_recursive_types
-- still working on it as it doesn't compile yet
-- In :: (Rec a -> a) -> Rec a
-- out :: Rec a -> (Rec a -> a)
-- newType Rec a = In { out :: Rec a -> a }
-- y :: (a -> a) -> a
-- y = \f -> (\x -> f (out x x)) (In (\x -> f (out x x)))
-- Using same improver function as the fixed-point combinator
-- fact'' :: Int -> Int
-- fact'' = y fact_improver
-- ----------------------------------------------------------------------
test :: Int -> [(Int,Bool)]
test n =
[ (x, fact x == fact' x) | x <- [0..n] ]
-- let internal_test = (fact x == fact' x) && (fact' x == fact'' x)
-- in [ (x, internal_test) | x <- [0..n] ]
-- test 7 => [(0,True),(1,True),(2,True),(3,True),(4,True),(5,True),(6,True),(7,True)]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment