You're very close. The answer is in choosing a correct f
. In particular, it's key that f
can depend on n
.
fun semifactorial n = reduce(fn (x,y) => x * y, 1, 1,
n, fn x => if x mod 2 = n mod 2 then x else 1)
should work.
Alternately, and a bit more cleanly:
fun foo n x = if (x + n) mod 2 = 0 then x else 1
fun semifactorial n = reduce((op* ), 1, 1, n, foo n x)
though this form does have potential to fail with particularly large values of n
and x
if your ML implementation doesn't support arbitrary precision integers.