【问题标题】:function which gets another function as argument in SML在 SML 中获取另一个函数作为参数的函数
【发布时间】:2018-04-14 02:50:32
【问题描述】:

考虑函数 g 获取 integer 并在 integer 大于之前确定的某个随机 const 正值时返回 true,否则返回 false。

我想在 SML 中编写一个函数 f,它将函数 g 作为参数。这个函数f 应该返回这个之前决定的随机 const 正值。

算法(用其他语言,C 或其他语言):

 int f(int num) {
     int num = 1;
     while(!g(num)) {
         num++;
     }
     return num;
 }

现在这是我在 SML 中尝试的:

fun f g = 
let
    val num = 1;
in
    while !(g num) do (
        val num = num + 1;
    );
    num
end;

但它不起作用。有什么建议么?

【问题讨论】:

  • 你的 C 代码应该是int f(bool (*g)(int)) {...,对吧?

标签: sml ml


【解决方案1】:
val num = num + 1;

首先val 只允许在顶层或let 内部。其次,它定义了一个新变量。所以在你的 C 代码中,它相当于:

int num = num + 1;

而不是:

num = num + 1;

换句话说,它创建一个新变量而不是修改现有变量,这在这里对您没有帮助。

所以自然而然的后续问题将是你如何做num = num + 1。最直接的答案是:你没有。 SML 中的所有变量都是不可变的,因此您不能重新分配变量。但是,您可以使用可变的refs 来解决此问题。

但是,在 SML 中执行此操作的正确方法是根本不使用 while 循环或重新分配,而是使用递归。

【讨论】:

  • 这里应该如何使用递归?
【解决方案2】:

正如 sepp2k 所解释的,您的问题与 g 的传递无关,而是您如何尝试定义循环。这是使用递归实现它的一种方法,这是您通常在 ML 中所做的:

fun f' g n = if g n then n else f' g (n + 1)
fun f g = f' g 1

或者,如果您想将辅助功能保留在本地:

fun f g =
  let fun loop n = if g n then n else loop (n + 1)
  in loop 1 end

【讨论】:

  • 谢谢!你如何测试它? val x = f g 什么?
  • 例如,val x = f (fn n => n*n = 256) 会为您找到 256 的平方根。
猜你喜欢
  • 2022-01-11
  • 1970-01-01
  • 2016-07-21
  • 1970-01-01
  • 1970-01-01
  • 2018-11-13
  • 2018-07-30
  • 2019-02-19
相关资源
最近更新 更多