如何将新值分配给用户定义的类型



我有这样的代码,我正试图将一张卡片插入一只手中。如果这只手是空的,我希望这只手握住正在插入的卡片,并指向下一只空的手。如果手不是空的,我想看看手上的下一张牌。一旦达到空手,我如何将手(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)

最新更新