^
この問題は、オペレーターだけでなく、はるかに広範囲に発生します。基本的に、OCamlコンパイラは、フォーマット文字列がリテラル文字列であることを認識している必要があり、リテラル文字列はコンパイル時に認識されている必要があります。そうでなければ、OCamlはコンパイル時に文字列をこのBLAHBLAH format6
タイプにキャストできません。このPrintf
モジュールは、コンパイル時に完全に認識されているフォーマット文字列、またはすでにBLAHBLAH format
型にキャストされているフォーマット文字列でのみ正しく機能します。
通常、この問題は、演算子を使用し、コードでこれらの文字列を使用する前に、すべてのリテラル文字列を型に^^
明示的にキャストすることで解決できます。BLAHBLAH format
別の例を次に示します。
# Printf.sprintf (if true then "%d" else "%d ") 2;;
Error: This expression has type string but an expression was expected of type
('a -> 'b, unit, string) format =
('a -> 'b, unit, string, string, string, string) format6
(* define a type abbreviation for brevity *)
# type ('a,'b) fformat = ('a ->'b, unit, string) format;;
type ('a, 'b) fformat = ('a -> 'b, unit, string) format
# Printf.sprintf (if true then ("%d":('a,'b)fformat) else ("%d ":('a,'b)fformat)) 2;;
- : string = "2"
if ... then "a" else "b"
OCamlシステムはにキャストできることを認識できませんBLAHBLAH format
。各リテラル文字列を自分でにキャストするBLAHBLAH format
と、すべてが機能します。(注: OCamlは文字列がリテラルであることを確認できないため、全体if/then/else
をにキャストしようとしても機能しません。)BLAHBLAH format
問題の原因は型の安全性の要件です。OCamlはすべてなどに正しい型の引数があることを要求し%d
、コンパイル時%s
にこれを保証します。コンパイル時にフォーマット文字列全体がわかっていない限り、で型の安全性を保証することはできません。したがって、たとえばランダムに選択するなど、複雑なアルゴリズムを介して計算されたフォーマット文字列で使用することはできません。Printf
Printf
%s
%d
フォーマット文字列を計算するために使用する場合if/then/else
、OCamlは複雑なアルゴリズムであり、コンパイル時に型の安全性を検証することはできません。オペレーターは型^^
について知ってBLAHBLAH format
おり、フォーマット文字列を連結するときに正しい結果を生成します。しかし、if/then/else
についてはわかりませんBLAHBLAH format
。また、に代わる組み込みの方法はありませんif/then/else
(ただし、そのようなことを自分で定義できると思います)。