2017-08-14 9 views
4

OCamlバージョン4.04のutopで関数fを定義します。OCamlの関数を優雅に無視する

utop # let f = function x -> x + 1;; 

val f : int -> int = <fun> 

fを無視しようとすると、警告が表示されます。

utop # let a = ignore (f : int -> int); f 2;; 

Characters 15-19:            
Warning 5: this function application is partial, 
maybe some arguments are missing 
val a : int = 3 

ignore次式が関数インタフェースint -> intを有するので、警告5がトリガされます。

ignore (f 0)およびif false then (ignore f 0)が機能しますが、エレガントではありません。私はfに欠落した議論を提供したくありません。 ignoreの代替手段はありますか?

ignoreのモチベーションは、このダミーの例ではあまり明確ではありませんが、実際のプロジェクトでは他の警告を避けるために使用する必要があります。

お時間をいただきありがとうございます。

+1

私はXY問題(http://xyproblem.info/)の匂いがします。本当のユースケースを説明できますか? – Drup

+1

関数を呼び出さない場合は、最初にその関数を使用するのはなぜですか? – Bergi

+0

実際の使用例は、ocaml_pluginを使用して実行時にOCamlコードをコンパイルする場合です。コード部分は 'f'を呼び出すこともあれば呼び出さないこともあります。私が 'f'をプラグインのライブラリとして使用したくないということを考えれば、' f'の定義にコードを追加することをお勧めします。 'f'を呼び出さなければ、コンパイラは文句を言うでしょう。 –

答えて

4

非常に大まかに以下のようにOCamlの型チェッカーによって処理された形態e1; e2の発現のために言えば:

  • e1は関数型t -> t'を持っている場合、警告5が放出されます。
  • else e1のタイプがunitではない場合、警告10が発行されます。例えば

ignore e1; e2

let f x = 
    prerr_endline "some side effect you may want"; 
    (* but you may not want the returned function sometimes *) 
    fun y -> x + y 

let a = f 1 2; f 1 2;;  (* Warning 10 *) 
let a = f 1; f 1 2;;   (* Warning 5 *) 

型チェックは、一点を除いe1; e2のものと同じである:それは第2のチェックをスキップ:e1の場合、警告10をも出射されていませんタイプはunitではありません。警告5のための最初のチェックがまだ実行されます。

let a = ignore (f 1 2); f 1 2;; (* No warning *) 
let a = ignore (f 1); f 1 2;; (* Warning 5 *) 

ignoreが10を警告除去するように設計されたので、ignoreのない5。この特別な処理は、OCamlのソースコード内のtyping/typecore.mlis_ignore funciton定義の周りにコード化されています。

あなたが本当に警告5を無視したい場合は、私は2つの方法を考える:

let a = let _ = f 1 in f 1 2;; (* No warning *) 

let ignore' _ =() 
let a = ignore' (f 1); f 1 2;; (* No warning *) 

最初のものは、ワイルドカードでパターンマッチングを使用することです。もう一つはあなた自身のignore関数ignore'を定義することです。これは通常のOCaml関数なので、前述の警告5を出すignoreという引数の特別な型チェックは行われません。

+0

fに欠落した引数を渡したくない場合はどうすればよいですか?このダミーの例では問題なく動作しますが、欠落している引数を構築するのが難しく、 'f'でいくつかの不適切な引数に例外が発生することがあります。 –

+0

'ignore'の後に関数interfaceの変数が続くと、コンパイラはいつも不平を言うことを指摘しています。 「無視する」という選択肢があるのだろうかと思います。ありがとう! –

0

次のように矢印の種類で動作し、独自の無視機能を定義することができます。

let ignore_fun (f:'a -> 'b) =() 

あなたは fをに引数を渡すことはもう必要がない、そのようにして生成文句を言わない、次の警告。camlspotterによって

let a = let _ = (f : int -> int) in f 2;; 
+0

警告27:未使用変数f。変数fはignore_funでは使用されないため、警告27がトリガされます。 –

+0

私は '' '' ignore_fun(_: 'a - >' b)=() '' ''と書くことができましたが、 – ghilesZ

1

あなたはlet _構築物によりignore呼び出しを置き換えることで警告を回避することができます。 私はちょうど第三の溶液を追加したいと思います:タプル

let a = ignore (f,()); f 2;; 

またはあなたの空想を取る

let a = ignore [f]; f 2;; 

または任意のリストに問題のある機能をラップします。

0

答えは結構です、あなたはそれを受け入れる必要があります。

let a = ignore_fun (f : int -> int); f 2;; 
関連する問題