2

简单的例子:我有一些函数,我需要全部调用它们,修改一个结构,只在一个函数中。使用这些简单的函数,任务可以不使用 void 的方式完成,但在其他任务中,您必须使用 void。所以,你可以做什么?

type player = { mutable name : string; mutable points : int } ;;

let putname brad = match brad with
  { name = x; points = y } -> { name = brad; points = y } ;;

let putpoint guy score = match guy with
  { name = x; points = y } -> { name = x; points = score } ;;

let loosers listplayer guy = guy :: listplayer ;;

这是问题 - 我该如何执行下一个功能?

let someoneloses guy = void

guy = putpoint guy 0 ;;
listplayer = loosers (listplayer guy) ;;
4

2 回答 2

1

鉴于您使用的名称是“void”,我假设您更熟悉 C(或 C++)。在 OCaml 中,“void”(无值类型的名称)的等价物是“unit”。但是还有另一个区别:虽然在 C 中语法足够复杂,以至于它没有值的构造(例如,您可以“return a_value;”或“return;”,关键字“”的两个不同但在语法上有效的用例return"),在 OCaml 中,语法更简单,并且总是需要一个值。所以我们有一个表示“无”的符号,巧妙地但也可能混淆地写成“()”。因此,C 的 OCaml 等价物:

void do_nothing(void) { return; }

写着:

let do_nothing () = ()

(请注意,一旦你掌握了“()”技巧,OCaml 语法就变得更简单、更容易理解了)。

现在希望这更清楚,回到你的问题。

什么都不返回的函数是一个返回“()”的函数,或者显式地(如上面的“do_nothing”)或者因为它以一个以“()”作为其值的表达式结尾。例如,一个作业(告诉我你会喜欢作业),例如:

let putpoint guy score = guy.points <- score

现在回到你的问题。您似乎正在做某种游戏,其中玩家表示为可变记录,并且随着游戏的发展,一些函数会修改这些记录。您不需要为此使用模式匹配。实际上,上面的“putpoint”等函数可能就是你想要的。但是你需要在你的程序中添加更多状态:例如,松散列表可能是对你修改的列表的引用等。

这是 OCaml 的“势在必行”的一面,但还有另一面,通常被认为更优雅,尽管通常通常较慢(但不是在为此技术优化的函数式语言中),包括避免改变状态(改变值事物),而是使用仅获取值和返回值的函数。像这样实现,玩家将被表示为一个不可变的记录,并且每个充当用户的函数都会接受一个“旧用户”并返回一个“新用户”,松手列表也是如此,依此类推。实际上,整个游戏状态将表示为一个很大的值,您的程序的“主循环”将在给定先前值以及可能的时间和用户输入的情况下计算“新状态”并返回它。

玩得开心!

此外,您的问题与 ocaml-batteries 无关。

于 2016-05-04T06:53:42.160 回答
0

由于您使用的是可变数据,因此您只需直接分配值。

let p = {name = "me";points=0};;
let update x = x.name <- "you";
x.points <- 3;;

update p ;;
于 2016-05-03T19:01:11.340 回答