Skip to content

Instantly share code, notes, and snippets.

@psmolak
Created January 11, 2019 20:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save psmolak/557dce8337fe94b2eb8af0f3b87ef1ea to your computer and use it in GitHub Desktop.
Save psmolak/557dce8337fe94b2eb8af0f3b87ef1ea to your computer and use it in GitHub Desktop.
{-# LANGUAGE Rank2Types #-}
newtype Church = Church (forall a. (a -> a) -> (a -> a))
zero' = Church (\f x -> x)
one' = Church (\f x -> f x)
two' = Church (\f x -> f $ f x)
three' = Church (\f x -> f $ f $ f x)
succ' (Church n) = Church (\f -> f . n f)
add' (Church a) (Church b) = Church (\f x -> b f $ a f x)
sub' a b = fromInteger $ max 0 (fromChurch a - fromChurch b)
mult' (Church a) (Church b) = Church (a . b)
fromChurch (Church n) = n (+ 1) 0
instance Eq Church where
(==) a b = (fromChurch a) == (fromChurch b)
instance Ord Church where
(<=) a b = (fromChurch a) <= (fromChurch b)
instance Show Church where
show n = show (fromChurch n)
instance Num Church where
(+) = add'
(-) = sub'
(*) = mult'
abs n = n
signum n = if (fromChurch n) == 0 then zero' else one'
fromInteger i = iterate succ' zero' !! (fromIntegral i)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment