【问题标题】:SML/NJ while loopSML/NJ while 循环
【发布时间】:2011-11-24 18:38:37
【问题描述】:

我对 SML 真的很陌生,但我不知道如何获得相同的答案;

它类似于:3^4 32 所以我的答案是 4(3 的幂),同样,如果我有数字 4 和 63,那么 4^263所以我的答案是 2(4 的幂)。

我想出了以下代码

val log (b, n) =
    let
        val counter = ref b
        val value = 0
    in
        while !counter > n do 
        ( counter := !counter*b 
          value := !value + 1)
    end;

所以这里的值是我需要的答案,但我得到了很多错误。我知道我在很多地方都错了。任何帮助将不胜感激。

我也许可以用普通的 ML 方法来做这件事,但我也想学习不纯的 ML...

fun loghelper(x,n,b) = if x>n then 0 else (1+loghelper((x*b),n,b)); 
fun log(b,n) = loghelper(b,n,b);

好的,所以最后这里是 while 循环的正确代码,它也可以正常工作;

      fun log (b, n) =
            let
               val counter = ref b
               val value = ref 0
            in
               while (!counter <= n) do 
               (counter := !counter*b; 
                value := !value + 1);
               !value
            end;

【问题讨论】:

    标签: while-loop sml smlnj


    【解决方案1】:

    您的代码中有几个问题:

    错误:

    • 应该是fun log (b, n) =,而不是val log (b, n) =fun 是一种方便的语法,可让您轻松定义函数。如果你想用val 写这个,你可以写:val log = fn (b, n) =&gt;(在递归函数或具有多个咖喱参数的函数的情况下会变得更复杂)
    • 您需要一个分号来分隔两个命令式语句:( counter := !counter*b; value := !value + 1)
    • value 必须是 ref: val value = ref 0

    逻辑:

    • 您的函数不返回任何内容。 while 循环具有单位类型,因此您的函数返回 ()(单位)。您可能想返回!value。为此,您需要在整个while 循环之后添加一个分号,然后编写!value
    • 您的 while 循环条件实际上没有意义。好像反过来了。你可能想要while !counter &lt;= n do
    • 您的基本情况不正确。 value 应该从 1 开始(因为 counterb 开始,bb 的第一次幂);或 counter 应该从 1 开始(因为 b 的零次方是 1)。您的功能版本也存在同样的问题。

    【讨论】:

    • 功能版本运行良好,但不纯版本需要您推荐的版本。非常感谢..我可能也应该发布更正的代码。
    • 确切地说,funval rec 的语法糖。我确定您已经知道@newacct,并且您只是为了简单的答案而对其进行了简化(等效于...)。不过我觉得还是值得一提的。
    • @Jesper.Reenberg:是的,我知道(我编辑了答案)。还有fun允许你写多个(咖喱)参数,而val你必须做fn a =&gt; fn b =&gt;
    • @newacct:也不错。我的意思是说这是一个很好的事实,因为他似乎不知道。不一定要更新您给出的“等价”,因为它完全等同于在您给出的示例中使用 val
    猜你喜欢
    • 2010-10-23
    • 2010-10-18
    • 2010-10-15
    • 1970-01-01
    • 1970-01-01
    • 2014-07-15
    • 2013-01-30
    • 2013-10-20
    • 2012-03-12
    相关资源
    最近更新 更多