2

簡単な例: いくつかの関数があり、1 つの関数でのみ構造を変更するためにそれらすべてを呼び出す必要があります。これらの単純な関数を使用すると、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 に答える