--
--  basic.hs
--
--  Basic definitions for playing with Church Numerals
--
--  Copyright (C) 2011 Martin Oldfield <m@mjo.tc>
--  
--  This file is free software; you can redistribute it and/or modify it
--  under the terms of the GNU Lesser General Public License as
--  published by the Free Software Foundation; either version 2.1 of the
--  License, or (at your option) any later version.
--

pp :: Num t => ((t -> t) -> t -> t) -> t
pp f = f (1+) 0

zero :: (t -> t) -> t -> t
zero f x = x

one :: (t -> t) -> t -> t
one f = f

two :: (t -> t) -> t -> t
two f = f . f

three :: (t -> t) -> t -> t
three f = f . f . f

(<*>) f g s  = (f . g) s

(<+>) f g s  = (f s) . (g s)

(<^>) f g    = g f

demo :: String
demo = concatMap test demo_data

test (ch, n) =     "N: "  ++ show n
               ++ " PP: " ++ show n'
               ++ ok (n == n') 
               ++ "\n"
    where n' = pp ch
          ok True  = " OK"
          ok False = " FAIL"

demo_data = zip [zero, one, two, three, four, five, six, seven, eight, nine ]
                [0 .. ]
    where four  = two   <*> two
          five  = two   <+> three
          six   = two   <*> three
          seven = six   <+> one
          eight = two   <^> three
          nine  = three <^> two


