【问题标题】:Using a particular higher-order helper function to compute factorial使用特定的高阶辅助函数来计算阶乘
【发布时间】:2019-07-19 06:00:42
【问题描述】:

我正在参加 MOOC(没有学分)。分配的问题之一是使用以下函数编写阶乘函数:

(’a->’a)->(’a->bool)->’a->’a

我已经创建了这个函数:

fun do_until (f, g) = fn x => case g(f x) of
              false => f x
            | _ => do_until(f,g) (f x);

但我在使用我的 do_until 函数来实现阶乘时遇到了困难。

我认为解决方案应该遵循以下格式:

fun factorial x = (do_until (f, g)) x

我看到的问题是“g”函数只能验证结果,如果验证,则返回该结果。由于函数类型描述符相当严格,它限制您将元组传递给 g,然后验证元组的一部分并返回另一部分。 IE。 (factorial, int to mult) 然后 g 将从 #2 验证并返回 #1。不幸的是,这些类型阻止了这一点。我开始认为使用 do_until 作为辅助函数是不可能的,除非您以其他方式计算阶乘,然后“g”只会将您的结果与该结果进行比较。如果我错了,请告诉我下一步该去哪里!

【问题讨论】:

    标签: sml


    【解决方案1】:

    你有错误的类型——函数应该被柯里化——如果你给参数提供比“f”和“g”更多的描述性名称,你可能会更幸运:

    fun do_until next done x = if done x 
                               then x
                               else do_until next done (next x) 
    

    请注意,您可以将任何从factorial 传递到do_until 的东西——例如一个保存你的计算状态的元组——然后在do_until 完成后“把它拆开”。 (我怀疑这就是你被卡住的原因。)

    【讨论】:

    • 好的,谢谢!这就是我最终要做的。我使用 let 表达式传入一个跟踪状态的元组。我不确定如果不这样做是否可行,因为“完成”功能必须只检查部分完成的阶乘
    • @poopsmith 如果你写了一个尾递归阶乘或循环,你还需要状态中的两个显式元素(即计数器和乘积)。如果你写一个非尾递归阶乘,看起来你只需要计数器,但状态的乘积部分隐含在暂停的递归调用中。
    猜你喜欢
    • 1970-01-01
    • 2023-03-22
    • 2015-04-19
    • 2015-01-08
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多