我有这样的代码,我正试图将一张卡片插入一只手中。如果这只手是空的,我希望这只手握住正在插入的卡片,并指向下一只空的手。如果手不是空的,我想看看手上的下一张牌。一旦达到空手,我如何将手(c,Empty)分配给它?
谢谢。
let rec insert c h = match h with
| Empty -> Hand (c, Empty)
| Hand (c', h') -> Hand (c', insert c h')
现在我在玩上面的代码。以下是输出示例:
# let hand0:hand = Hand ((Ace, Spades), Hand ((King, Diamonds), Empty));;
val hand0 : hand = Hand ((Ace, Spades), Hand ((King, Diamonds), Empty))
# insert (Ten, Hearts) hand0;;
- : hand = Hand ((Ten, Hearts), Empty)
# hand0;;
- : hand = Hand ((Ace, Spades), Hand ((King, Diamonds), Empty))
显然,hand0的内容没有改变。我真的不明白,一旦达到手的空值,我需要写什么来给它赋值。此外,我认为递归至少会显示手的第一部分(不为空的地方),但这也不起作用。我真的不明白为什么?
事实证明我做对了,只是没有正确调用函数。毫无理由地浪费几个小时。。
# let hand0:hand = Hand ((King, Spades), Empty);;
val hand0 : hand = Hand ((King, Spades), Empty)
# let hand0 = insert (Ace, Diamonds) hand0;;
val hand0 : hand = Hand ((King, Spades), Hand ((Ace, Diamonds), Empty))
在OCaml中,不能为变量赋值。任何变量。语言中没有语法可以做到这一点。
let someVar = something
声明并初始化let
主体中作用域中的新变量。一旦定义了变量,其值就不能更改。
在您的"答案"中,您在一个名为hand0
的外部作用域中定义了一个变量,然后在一个内部作用域中又定义了另一个(完全独立的)变量hand0
,它将hand0
隐藏在外部作用域之外。但是,您应该注意,这不会影响外部hand0
。你不妨给它起个不同的名字:
let hand0 = Hand ((King, Spades), Empty) in
let hand1 = insert (Ace, Diamonds) hand0 in ...
这看起来像是一个赋值,所以我觉得我应该给出一个提示。从本质上讲,你的第二个案例表明,你想扔掉c'
卡。您可以看到这一点,因为c'
没有显示在结果中。我认为您想要做的是保留c'
,所以您可能需要在结果中包含一个包含c'
的Hand
。我希望这能有所帮助。
我已经有一段时间没有研究ocaml语法了,但我确信你想要这样的东西:
Add last
let rec insert c h = match h with
Empty -> Hand (c, Empty)
| Hand (c', h') -> Hand (c', insert c h')
Add first is trivial
let insert c h = Hand (c, h)