それについて考えるための良い方法は、「私は(後で再びこの同じ機能を実行しているを含む)、それ以降の任意のコードがこれまでにおそらく値I以外見ることができる何かを変更したあります戻ってきた?もしそうなら、それは副作用です。そうでなければ、あなたはそれがないことを知ることができます。
だから、のようなもの:それはちょうど整数vより1である新しい値を返すため
let inc_nosf v = v+1
は副作用を持たないあなたはOCamlのトップレベルに次のコードを実行するのであれば、あなたが得ます。対応する結果:
# let x = 5;;
val x : int = 5
# inc_nosf x;;
- : int = 6
# x;;
- : int = 5
ご覧のとおり、xの値は変更されませんでした。戻り値を保存しなかったので、実際には何も増えませんでした。関数自体は、x自体ではなく戻り値を変更するだけです。だから、Xにそれを保存するために、私たちがしなければならないと思います。
# let x = inc_nosf x;;
val x : int = 6
# x;;
- : int = 6
inc_nosf関数は副作用を持たないので(つまり、それだけではない、他にすることによって、その戻り値を使用して外の世界と通信します変更)。
しかし、何かのように:それはrで表さ参照に格納された値が変更されるため
let inc_sf r = r := !r+1
は副作用があります。あなたはトップレベルで同様のコードを実行するのであれば、あなたの代わりに、これを取得:
# let y = ref 5;;
val y : int ref = {contents = 5}
# inc_sf y;;
- : unit =()
# y;;
- : int ref = {contents = 6}
ので、このケースでは、我々はまだ、戻り値を保存していないにもかかわらず、それはとにかくインクリメントました。つまり、戻り値以外に変更があったはずです。この場合、その変更は:=
を使用した割り当てで、refの格納値が変更されました。
Ocamlでは、ref、レコード、クラス、文字列、配列、およびハッシュテーブルの使用を避けると、副作用のリスクを避けることができます。 String.setやString.fillなどの関数を使用して文字列を修正しない限り、文字列リテラルを安全に使用できますが、基本的に、データ型を適切に変更できる関数は、副作用を引き起こします。
スタイルのヒント:「if式、true else else」パターンまたは他の同様のパターンは、初心者の間では非常に一般的です。それについて考えると、if部分を選択するには、式が真でなければならず、else部分についてはfalseでなければなりません。したがって、このパターンは削除して「式」に減らすことができます。 – LiKao
そのコードを表示できますか?私は間違いなく初心者であり、いくつかの指針を用いることができます。 –
確かに、それは非常に簡単です:if List.exists((=)7)myList then true true else ;; "あなたは単に "List.exists((=)7)myList ;;"と書くことができます。理由を考えるのをやめて、なぜこれら2つのステートメントが同じセマンティクスを持つのか、機能的な(そして一般的な)プログラミングについてたくさん学ぶでしょう。 – LiKao