【问题标题】:Confusing SML statement令人困惑的 SML 声明
【发布时间】:2013-12-16 03:56:10
【问题描述】:

我有这样的声明:

let val x = 
    let val x = 5
    in(fn y =>(y,x+y))
    end
     in
     let val y=3 and z=10
     in x z 
     end 
     end;

输出是:

(10,15)

我一直在尝试追踪这个答案是如何产生的,但我很困惑。有没有更好的方法来编写这个可以帮助我了解哪些变量在哪里使用?谢谢!

【问题讨论】:

    标签: sml smlnj


    【解决方案1】:

    首先,一些 alpha 转换:

    let val fnPairOfInputAndInputPlus5 = 
        let val five = 5
         in ( fn input => ( input, five + input ) )
        end
     in let val ignored = 3 and input = 10
         in fnPairOfInputAndInputPlus5 input 
        end 
    end;
    

    这段代码展示了当你声明一个函数值时,声明范围内的未绑定值,例如值five,被声明“包围”(因此称为“闭包”)。因此该函数总是返回一个由它的输入和它的输入加五组成的对。

    【讨论】:

    • 谢谢!这清楚了很多。我仍然对“fnPairofinputAndInputPlus5 输入”是什么感到困惑。您是在使用输入参数调用该值吗?
    • 正确。 ML 中的函数调用符号只是 f x( f x ) 用于函数 f 和参数 x。两个参数的函数可以接受一个带有两个参数 f (x,y) 的单个 tuple,或者它们可以是 curried 函数 f x y = ( f x ) y = ( ( f x ) y )。在后一种情况下,f x 返回另一个函数。
    【解决方案2】:

    你可以把它简化为

    let fun f y = (y,5+y)
        val y=3 and z=10
    in
      f z
    end;
    

    请注意,y 的两个实例是独立的。 x 的内部出现(我已经删除)独立于外部出现(现在重命名为 f)。

    【讨论】:

      【解决方案3】:

      可以通过人工评估和详细解释来理解。

      从你的初始表达开始:

      let val x = 
         let val x = 5
         in (fn y => (y,x + y))
         end
      in
         let val y = 3 and z = 10
         in x z 
         end 
      end;
      

      第 2,3,4 行是一个类型为函数的表达式,如您在 in 部分中所见。它不依赖于任何外部上下文,因此可以简化为只是fn y => (y, 5 + y),根据let 中给出的绑定将x 替换为5

      所以你现在有了这个:

      let val x = fn y => (y, 5 + y)
      in
         let val y = 3 and z = 10
         in x z 
         end 
      end;
      

      在替换 x 之后(并删除 let,现在不再需要):

      let val y = 3 and z = 10
      in (fn y => (y, 5 + y)) z 
      end;
      

      注意(y, 5 + y) 中出现的y 绑定到函数的参数,而不是3。没有引用这个外部的y,所以它的biding可能会被删除。

      现在你有:

      let z = 10
      in (fn y => (y, 5 + y)) z 
      end;
      

      z 替换为10 并删除不再需要的let,您将得到:

      (fn y => (y, 5 + y)) 10;
      

      这是一个功能应用程序。你可以评估它,得到:

      (10, 5 + 10);
      

      这给出了您注意到的最终和恒定的结果:

      (10, 15);
      

      【讨论】:

        猜你喜欢
        • 2011-02-03
        • 1970-01-01
        • 2021-06-13
        • 1970-01-01
        • 2019-01-31
        • 2021-04-23
        • 2019-12-23
        • 2011-07-24
        • 2012-11-08
        相关资源
        最近更新 更多