【问题标题】:ML variables in functions函数中的 ML 变量
【发布时间】:2014-12-22 05:54:00
【问题描述】:

对于这个看似简单的 SML 问题,我似乎找不到简单的答案。我有代码:

    fun inde(x, y, L) = if null L then nil else
    if x=hd(L) then y+1::inde(x,y+1,tl L) else
    inde(x,y+1,tl L);

我希望 y 是函数外部的变量,所以它会是 inde(x,L) 但 y 仍然可以正确计数。当我在函数外部声明它(为0)时,当函数被递归调用时,它会重置为0。

如果您要运行这个当前函数,它会生成一个列表,其中列出了 x 在列表 (L) 中的位置。 所以 inde(1,0,[1,2,2,1,1]) 会产生 [1,4,5]

【问题讨论】:

  • 标准 ML 中的变量是实际的数学变量,其含义是通过替换给出的,而不是通过一系列重新分配。 Source。这样做的直接后果是您无法修改变量在给定上下文中代表的值。

标签: function variables helper sml ml


【解决方案1】:

使用函数式编程风格时的惯用结构是定义一个内部函数,该函数接受程序员感兴趣的参数,而不是用户感兴趣的参数,然后从主函数调用内部函数:

fun inde(x : int, L) =
  let
    fun inner(list1, list2, y : int) =
      if null list1 
      then List.rev list2 
      else
        if x = hd list1
        then
          inner(tl list1, y::list2, y + 1)
        else
          inner(tl list1, list2, y +1)
    in
      inner(L,[],1)
    end

在示例函数中:

  • inner 使用四个值:局部变量 list1list2y。它还使用封闭范围内的x

  • inner 构建(conses up)将使用list2 返回的列表。它通过从SML Basis Library 调用List.rev 来反转列表。这会使执行时间增加 O(n)。

  • let...in...end 构造的最后一部分:inner(L,[],1) 被称为“蹦床”,因为代码一直到达源文件的底部,然后从它反弹开始执行。这是标准模式。

  • 请注意,我开始迭代时 y 等于 1,而不是 0。从零开始在原始文件中没有完成任何操作。

【讨论】:

  • inner 的命名约定是什么?我倾向于使用fun bla ... let fun bla_ ... in bla_ ... 我认为有更好的方法,因为这显然是受 Python 的影响,而且我在使用 Python 之前使用 ML 进行编程。
  • @rudolfovic 我将函数命名为“内部”,因为我的回答说明了内部函数的使用[请参阅我的回答的非代码文本]。命名是 Martin Fowler 在计算机科学中的两个难题之一。我并不是说“inner”是个好名字,但两年后,我可以阅读我的代码并解释为什么我将内部函数命名为“inner”......以及为什么我将外部函数命名为“inde”。因此,如果有一个约定,那就是主要为人类阅读而编写的程序。祝你好运。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-18
  • 2021-12-07
  • 2013-04-14
  • 2013-11-16
  • 2020-09-28
相关资源
最近更新 更多