2

I have an assignment that involves making church numerals in SML. I've looked around and just can't find what I'm doing wrong. The goal is to make a function that takes an int and returns a church numeral, defined as datatype 'a numeral = Num of ('a -> 'a) -> 'a -> 'a (which is predefined by my teacher). Then to make a second function that takes a church numeral and returns an int.

I saw a previous post with the code:

val ZERO = C(fn (f,x) => x)
fun subCreate 0 (f,x) = x
   | subCreate n (f,x) = f (subCreate (n-1) (f,x))
fun create n = C(fn (f,x) => subCreate n (f,x));
fun churchToInt (c, cn) = cn ((fn x => x+1), 0) 0;

but this does not work, and gives the error type vars not generalized because of value restriction are instantiated to dummy types.

When I used the code:

val zero = fn s => fn x => x; 

(to define a zero) and then

val next = fn n => fn s => fn x => (f ((n s) x));

(just to do a test to see if I could increment zero, before setting up an iterative or recursive function), I got the same error. I've spent hours on this problem, unable to produce a church numeral. Can someone point me in the right direction?

ruakh
  • 175,680
  • 26
  • 273
  • 307
Arsarcanum
  • 21
  • 3

1 Answers1

2

I think you are running into the "value polymorphism" in SML'97. Here is a very long section of documentation discussing it.

One workaround is, whenever you have an expression which causes this problem, e.g. next zero, wrap a function around it, e.g. fn x => next zero x.

Another thing I think you could do is instead of evaluating definitions at the top level in the interpreter, wrap the definition and all the code that uses it into local scope (e.g. inside let ... in ... end) or into functions.

newacct
  • 119,665
  • 29
  • 163
  • 224
  • I tried the wrapping after I wrote this post and it didn't help lol, same issue. I'll check the documentation you linked next. – Arsarcanum Feb 06 '12 at 19:43