{-# LANGUAGE Rank2Types #-}moduleControl.ChurchwhereimportPreludehiding(succ,and,or){--
Semantics of nx in the language HA! ... it can be something other than Peano.
Hm.
Let's think about this. If the Peano-numeral have a Church-numeral semantics
then multiplication and exponentiation is a SNAP! (But addition, without
pattern-matching and destructuring are a BEAR!)
And subtraction ...? Don't even get me started on that.
Just ... don't.
So! BONUS!
We extend our language HA! with the symbol (\) and the semantics of (->) in
definitions, and the type-variable names tx [x = 0, 1, 2, ..] in declarations.
So, given the declaration of the Church numeral in the meta-language: --}typeChurcht1=forallt1.(t1->t1)->t1->t1{--
A Church numeral, n, is applying a function, f, to some value, x, n times.
So, zero is f applied zero times to x, giving just x, one is applied once to
x, giving f x, and plus m n is m f applications FOLLOWED BY n f applications
to x. So extending HA! with the type Church, Use the Church numerals of --}zero::Churcht1zero=undefinedone::Churcht1one=undefined{-- (well, define those numerals, anyway). With the above numerals, define
plus, from plus, define succ, then mult and pow.
... The function pow, if you're familiar with exponentiation-as-
function-application, is really, really simple using Church numerals. --}plus::Churcht1->Churcht1->Churcht1plusn1n2=undefinedsucc::Churcht1->Churcht1succn1=undefined-- so, actually, one is superfluous in light of zero and succ, so let's-- define some other numerals:two,three,four,five,six::Churcht1two=succonethree=succtwofour=succthreefive=succfoursix=succfive-- ... etc.-- mult is n1 applications of n2 applications of the function over some value:mult::Churcht1->Churcht1->Churcht1multn1n2=undefined-- pow is really, really easy to define with regard to n1 and n2, but the-- typing in Haskell can trip things up :/ ... edit: solved this with forall.pow::Churcht1->Churcht1->Churcht1pown1n2=undefined{--
Demonstrate that mult and pow do (ITRW) what they promise (ITCU)
ITRW: 'in the real world'
ITCU: 'in the church universe'
Now, booleans are also really simple using Church representations:
True is that when given two values, the first is returned
False is that when given two values, the second is returned
So, we extend HA!-language once more with the type ChurchBool
defined in the meta-langauge and the predicate values px and qx
for [x = 0, 1, 2, ...]
--}typeChurchBoolt1=forallt1.t1->t1->t1true::ChurchBoolt1true=undefinedfalse::ChurchBoolt1false=undefined-- with the above, define the 'and' and 'or' functions. Verify their veracity:and::ChurchBoolt1->ChurchBoolt1->ChurchBoolt1andp0q0=undefinedor::ChurchBoolt1->ChurchBoolt1->ChurchBoolt1orp0q0=undefined-- for both the Church numerals and Church booleans you can use the -- meta-language to help you with verifying your definitions.