Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 方案任务分解-全局变量问题_List_Variables_Scheme - Fatal编程技术网

List 方案任务分解-全局变量问题

List 方案任务分解-全局变量问题,list,variables,scheme,List,Variables,Scheme,这是我的问题(概括为一个抽象的情况)。它通常是一个口译员 我有一个程序,需要解析一个输入列表,并根据其元素顺序调用一些需要修改变量的函数。函数由单独定义和选择(cond。我需要更新的这3个变量包含有关当前情况的信息(精确-机器人位置、迷宫和机器人方向)。上一个函数的结果将用于下一个函数(即使用更新的变量) (定义func-a…) (定义函数b…) (定义(主功能) 在这里,我解析列表并选择调用哪个函数 ;输出必须包含(列表)) ) 我可以使用什么方案工具来更新这些变量?我考虑过几个选择: 使

这是我的问题(概括为一个抽象的情况)。它通常是一个口译员

我有一个程序,需要解析一个输入列表,并根据其元素顺序调用一些需要修改变量的函数。函数由单独定义和选择(cond。我需要更新的这3个变量包含有关当前情况的信息(精确-机器人位置、迷宫和机器人方向)。上一个函数的结果将用于下一个函数(即使用更新的变量)

(定义func-a…)
(定义函数b…)
(定义(主功能)
在这里,我解析列表并选择调用哪个函数
;输出必须包含(列表))
)
我可以使用什么方案工具来更新这些变量?我考虑过几个选择:

  • 使用(定义然后调用set!(这是一种糟糕的风格,因为它不是纯函数式编程)
  • 从头到尾调用函数(这不起作用:我还必须检查移动是否有效)
  • 不要让这些变量保持不变,尝试将它们作为参数传递给每个函数

还有其他合适的方法吗?

仅仅因为Scheme被认为是一种“函数式语言”,并不禁止您使用“set!”——毕竟它存在于要使用的语言中。因此:

(define-record-type position (fields x y z))

(define robot-position (make-position 0.0 0.0 0.0))

(define update-robot-position (new-x new-y new-z)
  (set! robot-position (make-position new-x new-y new-x)))
[我选择将位置定义为不变。]


如果愿意,您可以选择另一种方法,但从根本上说,机器人的位置发生了变化,这种变化将以某种方式出现在您的代码中。为什么不使用最简单、最直接的方法呢?

您必须保持某种状态(以及读取文件),因此将不会有纯函数式编程,您必须接受一些偏差

一般的方法是将共享对象保持为某个元函数中的本地对象,例如
parse
,并通过调用您的函数来更新它,例如
parse one
parse two
,等等

现在,您需要一种方法来更新它们

通过在范围内定义它们,可以使它们在
parse one
parse two
中可见:

(let ((state (make-state)))
  (let ((parse-one (lambda () ...))
        (parse-two (lambda () ...)))
    ....))
或者使用返回值:

(let ((state (make-state)))
  ...
  (set! state (parse-one state))
  ...)
还有第三种方法,称为OOP。在一个闭包中定义所有这些方法,以便它们可以共享一些数据:

(define (make-parser)
  (let ((state (make-state))
    (let (((parse-one (lambda () ...))
          ((parse-two (lambda () ...))
          ((get-state (lambda () state)))
       (list parse-one parse-two get-state))))

(destructuring-bind (parse-one parse-two get-state) (make-parser)
  ...
  (parse-one)
  ...
  (get-state))

(这只是一种简单的销毁列表的方法,请参阅),但它似乎是第一种方法的复杂版本。

我认为,您需要更具体一些。方法总是取决于问题,并且您提供的信息量是不够的。我将使用您的第三种选择,传递三个变量(表示状态)从函数到另一个函数(最好是在尾部调用中)。您还可以在更新它们时将这些三元组收集到列表中,从而创建一个显式的评估历史(如果您的机器人试图解决迷宫问题,可能会很有用)-增加列表,例如,如果你坚持走这条黑暗而曲折的道路,试图在处理国家问题时保持纯粹的功能性,你最终将进入单子王国。
(define (make-parser)
  (let ((state (make-state))
    (let (((parse-one (lambda () ...))
          ((parse-two (lambda () ...))
          ((get-state (lambda () state)))
       (list parse-one parse-two get-state))))

(destructuring-bind (parse-one parse-two get-state) (make-parser)
  ...
  (parse-one)
  ...
  (get-state))