0

I'm practicing with OCaml compiler and I'm doing a small assignment where we have to implement Church numerals defined as:

zz = pair c0 c0; ss = λp. pair ( snd p) ( plus c1 (snd p)); prd = λm. fst (m ss zz );

and to calculate the ss i wanna implement plus:

plus = λm. λn. λs. λz. m s (n s z)

so my question is, how to implement funtion plus, like n times succ 0?

I've tried like plus = lambda m. lambda n. lambda s. lambda z. m s (n s z); but it is not correct in the compiler.

I've notice that I work in the OCaml compiler and write all my functions in the func.f file not in the .ml file

https://www.cis.upenn.edu/~bcpierce/tapl/ code is from there, fulluntyped folder

glennsl
  • 28,186
  • 12
  • 57
  • 75
Zethuman
  • 59
  • 2
  • I don't have an answer because I don't really understand your question, I'm afraid. First, are you working with OCaml the language, or are you working with the OCaml compiler (the implementation, ie.. compiler internals)? I assume you're working with OCaml the language as that's what Pierce is doing. If you're working with OCaml then you should know that there's no keyword `lambda` in OCaml. Your code isn't even close to valid OCaml. It seems to me the main thing you need to do next is to learn enough OCaml to proceed. You could try the tutorial resources at ocaml.org. – Jeffrey Scofield Mar 17 '21 at 05:11
  • @JeffreyScofield You understood correctly, the task was not explained to me enough. But I am trying to understand, reading the book, but I cannot implement in the code what is written in the book. The fact that the ```lambda``` keyword does not exist on OCaml I know, it is defined in the lexer.ml (you can see it in the link which I send) and it turns out to be manually added. I implemented not or xor nand, but now I'm stuck on a plus, since I have no idea how to iterate and there are no resources in the Internet. Thanks for the comment – Zethuman Mar 17 '21 at 05:22
  • OK, so you seem to be asking what input you can give to Pierce's interpreter. That's why you're saying it goes in the `.f` file. Sadly I'm not familiar with these Pierce exercises, so I can't really help. This seems a bit too specialized for StackOverflow (but maybe not, it's a classic textbook). If you're taking a course you could try asking the professor or the TA. – Jeffrey Scofield Mar 17 '21 at 06:32
  • Thank you, that was what I wanted to say. The professor has no opportunity to ask for a number of reasons, I thought somebody could help here. – Zethuman Mar 17 '21 at 07:49

1 Answers1

0

Instead of lambda as in lambda calculus, you use fun to encode Church numerals in OCaml. You define numerals as functions that takes a unary function (named s for "successor") and base value (z for "zero"). For example, three is:

# let three = fun s z -> (s (s (s z)));;
val three : ('a -> 'a) -> 'a -> 'a = <fun>

If you want to translate this representation to an OCaml integer, you define:

# let int_succ x = x + 1;;

Then you can have the OCaml integer representation of three by calling it like so:

# three int_succ 0;;
- : int = 3

It effectively calls int_succ successively on 0, on the innermost result (ie. 1), etc. until you get 3.

But you can manipulate those numbers in their Church representation as follows. For example, to compute the successor Church number of an arbitrary Churn number n:

# let succ n = fun s z -> (s (n s z));;

We have to return a Church number, the result is a function of two parameters, s and z. It also takes a single input, a church number n. The result is calling s on (n s z), namely the successor of number n. For example:

# (succ three) int_succ 0;;
- : int = 4

Likewise, we can define add:

# let add x y = (fun s z -> (x s (y s z)));;
val add : ('a -> 'b -> 'c) -> ('a -> 'd -> 'b) -> 'a -> 'd -> 'c = <fun>

Here, the function takes two numbers. The expression (y s z) represents the computation made on number y, and it is used as the base value when applying x in (x s (y s z)). If you use int_succ and 0 for s and z, you can see that (y s z) will increment from 0 as many times as encoded by y, then increment from that value as many times as encoded by x.

For example:

# let two = fun s z -> (s (s z)) ;;
val two : ('a -> 'a) -> 'a -> 'a = <fun>

Then:

# let five = add two three;;
val five : ('_weak4 -> '_weak4) -> '_weak4 -> '_weak4 = <fun>

Notice that the types are weak, you don't need to worry too much about it but that means that once you call five with a given s and z, you won't be able to reuse five with different types.

# five int_succ 0;;
- : int = 5

And now, the type is fully known:

# five;;
- : (int -> int) -> int -> int = <fun>
coredump
  • 37,664
  • 5
  • 43
  • 77
  • Thank you for youe answer, but it is seems like not answer for my question. I work with a https://github.com/roehst/tapl-implementations/tree/master/fulluntyped. I understood what you are answered, but in my situation there is no types in there. I have only booleans and lambda calculus. Please review code in the link which I send. – Zethuman Mar 18 '21 at 02:19
  • It looks like function application in that untyped language accepts only one argument, you may need to add parentheses to call e g (f x y) as ((f x) y). – coredump Mar 18 '21 at 06:54