【问题标题】:SML - changing the value of a tuple element in a list of tuplesSML - 更改元组列表中元组元素的值
【发布时间】:2017-01-31 11:10:24
【问题描述】:

我刚开始学习 SML,我想编写一个程序,它需要 2 个 int 和一个元组列表,对它们进行更改,然后返回一个列表(BOXES 是一个列表)。列表总是有 2 个元组。在某些情况下,我需要更改元组中元素的数量。例如,我定义 Xb1 并给它元组的第一个元素的数量( #1 head ),然后我更改代码中 Xb1 的数量(并返回列表)。但问题是这个数额没有改变。 代码如下:

fun MoveBoxL(Xw,Yw,boxes:(int * int)list) : BOXES =
let
val head = List.hd boxes
val tail = List.hd boxes
val Xb1= #1(head)
val Yb1 = #2(head)
val Xb2 = #1(tail)
val Yb2 = #2(tail)
in
if Yw=1 then boxes
else if head=(Xw,1) andalso Yw=2 then boxes
else if tail=(Xw,1) andalso Yw=2 then boxes
else if Yw=3 andalso head=(Xw,1) andalso tail=(Xw,2) then boxes
else if Yw=3 andalso tail=(Xw,1) andalso head=(Xw,2) then boxes
else if head=(Xw, Yw-2) andalso tail=(Xw, Yw-1) then (Yb1=Yb1-1 ; Yb2=Yb2-1 ; boxes)
else if head=(Xw, Yw-1) andalso tail=(Xw, Yw-2) then (Yb2=Yb2-1 ; Yb1=Yb1-1 ; boxes)
else if head=(Xw,Yw-1) then (Yb1=Yb1-1 ; boxes)
else if tail=(Xw,Yw-1) then (Yb2=Yb2-1 ; boxes)
else boxes
end;

cpn tools picture 怎么了?

【问题讨论】:

  • (Yb1=Yb1-1 ; Yb2=Yb2-1 ; boxes) 毫无意义。它只返回boxes。您的所有子句无一例外地返回boxes 不变。你在思考。 boxes 不会改变。 Yb1 = Yb1-1 也只是一个平等测试。它返回值 false,然后将其丢弃。你似乎试图用(Yb1=Yb1-1 ; Yb2=Yb2-1 ; boxes) 做某种let ... in ... end 构造。无论如何——您应该显示BOXES 的定义。我们不必猜测它是什么。
  • 那么我怎样才能改变 Yb1 和 ... 的数量?如何增加或减少金额,然后返回更改后的值?
  • 在这种情况下直接返回您希望boxes 的值。我真的不太确定那是什么,因为我发现您的代码的意图有些模糊。
  • 如果你提供一些有代表性的输入和预期的输出可能会有所帮助。说明你希望MoveBox 会做什么。它与框和动作有什么关系?
  • 我正在使用 cpn 工具,模拟一个像推箱子这样的游戏,其中一个人试图将 2 个盒子移动到所需的位置,这个函数用于将盒子移动到左边。所以每次它以工人的位置(Xw,Yw)和盒子的位置(作为一个列表)作为输入,并决定盒子是否可以向左移动。当盒子返回不变时,意味着它们不能向左移动,每次它改变时,这意味着盒子可以移动,所以值应该改变。问题是我不知道如何直接改变列表中元组的值。

标签: sml


【解决方案1】:

我仍然不能 100% 确定这些移动盒子的规则是什么,但以下内容似乎抓住了您的意图:

fun MoveBoxL(Xw,Yw,boxes:(int * int)list) =
let
   val [box1,box2] = boxes
   val (Xb1,Yb1) = box1
   val (Xb2,Yb2) = box2
in
   if Yw = 1 then boxes
   else if box1=(Xw,1) andalso Yw=2 then boxes
   else if box2=(Xw,1) andalso Yw=2 then boxes
   else if Yw=3 andalso box1=(Xw,1) andalso box2=(Xw,2) then boxes
   else if Yw=3 andalso box2=(Xw,1) andalso box1=(Xw,2) then boxes
   else if box1=(Xw, Yw-2) andalso box2=(Xw, Yw-1) then [(Xb1,Yb1-1),(Xb2,Yb2-1)]
   else if box1=(Xw, Yw-1) andalso box2=(Xw, Yw-2) then [(Xb1,Yb1-1),(Xb2,Yb2-1)]
   else if box1=(Xw,Yw-1) then [(Xb1,Yb1-1),box2]
   else if box2=(Xw,Yw-1) then [box1,(Xb2,Yb2-1)]
   else boxes
end;

我将您的 headtail 分别重命名为 box1box2。 (并修复了您给tail 提供错误值的错误)并使用模式匹配使绑定更易于理解。更重要的是,我换了

(Yb1=Yb1-1 ; Yb2=Yb2-1 ; boxes)

[(Xb1,Yb1-1),(Xb2,Yb2-1)]

当我说你应该直接返回你想要的新值时,这就是我在 cmets 中的意思。

似乎可以通过使用orelse将具有相同返回值的子句组合成单个条件来清理逻辑。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多