I know I can write the y-combinator in SML like this: First declare a new datatype to bypass the type mismatch due to circularity.
datatype 'a mu = Roll of ('a mu -> 'a)
val unroll = fn Roll x => x
Now you can easily define the y-combinator:
val Y = fn f => (fn x => fn a => f (unroll x x) a)
(Roll (fn x => fn a => f (unroll x x) a)))
Then you are done, you can use it like this:
val f = Y (fn f => fn n => if n = 0 then 1 else n * f (n-1))
My question is: Are there other ways of implementing the y-combinator in SML?