tags:

views:

222

answers:

1

I have an assignment where I have to implement church numerals in sml using the datatype: datatype 'a church = C of ('a -'a) * 'a -> 'a I have to write the function create :int -> 'a church and a function churchToint so far I have the following code:

datatype 'a church = C of ('a -> 'a) * 'a -> 'a
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 cn = cn (fn x => x + 1) 0;

I know i am pretty close but not quite. Can you please tell me where I am going wrong? Thanks

A: 

You are right, you are quite close. There are only two minor mistakes in your churchToInt function:

  1. You're not unpacking the church numeral. I.e. you treat your argument cn like a function, but churchToInt should accept a C containing a function, not a function itself. So change it to fun churchToInt (C cn) =, to unpack the function via pattern matching.

  2. You're applying two arguments to the function using curry style, but C has been defined to contain a function taking a tuple. So instead of cn (fn x => x+1) 0, write cn ((fn x => x+1), 0).

With these two changes your code works fine.

sepp2k
I did that however is still get churchToInt:int church -> int instead of 'a church. And in addition, when I run for example:create 5; I get: "Warning type cars not generalized because of value restriction are instantiated to dummy types (X1,X2,....)val it = C fn : ?.X1 church "
duby12
@tester: Of course the type is `int church -> int`. If the type were `'a church -> int`, you wouldn't be allowed to pass in a function of type `int -> int`. If the assignment really requires you to define a function of type `'a church -> int`, I dare say it's not solvable - at least not with the given type definition.
sepp2k
but what about the function create, I mean it's working for example churchToInt (create 5) returns 5 but whenever I run create it keeps giving me that weird error
duby12
@tester: It's not an error. It's a warning. If you want to, you can make it go away by giving it an explicit type. E.g. `val myCn : int church = create 5` will compile and run without warning.
sepp2k