我正在遵循标准ML的本教程:http://homepages.inf.ed.ac.uk/stg/NOTES/node2.html,我遇到了这个问题:
如果n是奇数,则正整数n的半保密是1×3×5×...×n,如果n是偶数,则是2×4×6×...×n。使用reduce函数定义一个semifac函数,用于计算semifactorials。
Reduce定义为:
fun reduce (g, e, m, n, f) =
if m > n then e else g (reduce (g, e, m, n-1, f), f n);
我花了几个小时搞乱这个问题,找不到令人满意的答案,不需要改变reduce功能。如果您将reduce重新定义为:
,问题就变得容易了fun reduce' (g, e, m, n, f) =
if m > n then e else g (reduce'(g, e, m, n-2, f), f n);
最终解决方案为:
fun semifactorial n = reduce'(fn (x,y) => x * y, 1, 1, n, fn x=>x);
我认为这是作者想要的,但我不确定。无论如何要解决这个问题而不改变reduce的定义?我认为有一些非常明显的功能方法可以做到这一点,但我看不出如何将减少量减少2而不是1(我的直觉说答案在于为g和f选择正确的函数值)。
答案 0 :(得分:1)
您可以使用f
来决定是否将索引相乘。如果奇偶校验相同,它应该只乘以它们。
fun sfact n = reduce(op*, 1, 1, n, fn k => if n mod 2 + k mod 2 = 1 then 1 else k);
答案 1 :(得分:1)
你非常接近。答案是选择正确的f
。特别是f
依赖于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)
应该有用。
或者,更干净一点:
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)
如果您的ML实现不支持任意精度整数,则此表单可能会因n
和x
的特别大的值而失败。