1

I'm trying to write out some lambda calculus, but I can't get church conditionals to work. I should probably say that I'm a Haskell noob.

I've looked at solutions online and on SO, but they all involve introducing a new type and other tricks, but I want to keep it as close to the original syntax as possible. For example:

tru :: Integer -> Integer -> Integer
tru = \x -> \y -> x

fals :: Integer -> Integer -> Integer
fals = \x -> \y -> y

main = do
  print (tru 2 3)
  print (fals 5 6)

Matches the exact syntax for church booleans:

\a.\b.a
\a.\b.b 

Any way to match the exact syntax for church if/else? I'm trying to replicate \p.\a.\b.p a b, but I'm not sure what I'm doing wrong:

ifelse :: Integer -> Integer -> Integer -> Integer -> Integer -> Integer
ifelse = \p -> \a -> \b -> p -> a -> b

main = do
  print (tru 2 3)
  print (fals 5 6)
  print (ifelse tru 42 58)
antimatter
  • 3,240
  • 2
  • 23
  • 34

1 Answers1

7

You want something like

ifelse :: (Integer -> Integer -> Integer) -> Integer -> Integer -> Integer
ifelse = \p -> \a -> \b -> p a b

or even

ifelse = id

Also keep in mind that your Church booleans can only be applied to integers, which can be restrictive. You can make your encodings a bit more general by giving them a polymorphic type.

-- Warning: untested
{-# LANGUAGE RankNTypes #-}
type Cbool = forall a. a->a->a
tru :: Cbool
tru = const
fals :: Cbool
fals = const id
ifelse :: Cbool -> a -> a -> a
ifelse = id
type Cnat = forall a. (a->a)->a->a
zero :: Cnat
zero = \s z -> z   -- const id
-- etc
chi
  • 111,837
  • 3
  • 133
  • 218
  • 2
    I note here that if we want to do exponentiation on Church numerals then the rank-n type is actually required. – András Kovács Apr 17 '14 at 09:28
  • 3
    @AndrásKovács Really RankNTypes should be necessary for all church numerals, `CNum = forall c. (c -> c) -> c -> c`. Otherwise, you can break parametricity and return something that isn't a church numeral using the OP's code, like `-1`. – daniel gratzer Apr 17 '14 at 11:43
  • Thanks, this helps a lot. Just a question though: are there any limitations to using church encodings? Could you, for example, write an entire programming language with them? assuming that you could convert the representation back to something that's readable to the end-user? – antimatter Apr 17 '14 at 22:22
  • 1
    @gyeh you can use the Church encoding to represent any algebraic data type, and express the typical construction/destruction (aka pattern matching) mechanisms you find in functional languages. If you further add unconstrained recursion (or some fixed point combinator), you get a Turing-powerful programming language. Not a very user-friendly one, though ;-) Of course, while you can express any computation in this language, you will still lack I/O primitives (filesystem access, network, graphics, sound, ...) – chi Apr 18 '14 at 00:21
  • Yeah, the `forall` is restricts it to only what you want (and actually gives the end user more freedom.) – PyRulez Aug 29 '15 at 16:48