5

関数の戻り値をうまく捨てて、ユニットを返すかのように扱うにはどうすればよいですか (明らかに副作用のため)。明白なアプローチはこれを行うことです:

let foo = begin
  some_ignored_thing ();
  actual_return
end

ただし、コンパイラは、戻り値の型がsome_ignored_thingユニットではないことを (警告と共に) 訴えます。

次のような独自の方法を発明できます。

let ignore a = ()

少なくとも簡潔に見え、何かが起こっていることを示していますが、同じことを達成する言語/標準ライブラリには何かありますか? 比較的一般的な使用例だと思いました。

4

1 に答える 1

11

実際、ignore : 'a -> unitまさにこれを行う関数があります。

コンパイラは実際にignore特定の動作を認識し、ハードコーディングします。これは一般的には非常に便利ですが、場合によっては不便な場合もあります。デフォルトでは、関数 (形式の型を持つもの) を無視するとfoo -> bar警告が発生します。

その理由は、関数の最後の引数を追加するのを忘れることは、比較的よくある間違いだからです。たとえば、次のように書くことができます

ignore (List.map (fun x -> foo bar))

あなたが書くつもりだった間

ignore (List.map (fun x -> foo bar) li)

適用されると期待される効果は適用されません。

したがってignore、この場合は警告が発生しますが、手動でコーディングした場合は発生let ignore x = ()しません。人も時々書きます

let _ = foo in ...

を無視fooしますが、これには同じ欠点があります (型が実際に何であるかについて間違っているのは簡単です)。Kakadu はそこで型注釈を使用することを推奨していますが、これは妥当なアドバイスです。

let _ = ...(プログラムの「メイン」式に使用する人もいますlet () = ...。型の精度を強制するという同じ理由で、むしろ使用することをお勧めします。)

最後に、使用すると括弧または を追加する必要がlet _ = ...ある状況にあるため、フォームを使用することを好む人もいます。常に括弧を追加することをお勧めします。このような場合は、括弧を付けることで自分自身を簡単に撃つことができます。たとえば、あいまいな優先規則です。;begin..endbegin..endif..then..else..

于 2013-03-06T11:12:39.393 に答える