このコードで遊んでいましたが、何かわかりません。
type t1 = [ `A ];;
type t2 = [ t1 | `B ] ;;
type t3 = [ t2 | `C ] ;;
module type MT =
sig
type ('a,'b) fct
val create : ('a -> 'b) -> ('a,'b) fct
end;;
module Mt : MT =
struct
type ('a,'b) fct = 'a -> 'b
let create f = f
end;;
let f = (fun x -> x : t2 -> t2) ;;
let af = Mt.create (fun x -> x : t2 -> t2);;
(f :> t1 -> t3);;
(af :> (t1, t3) Mt.fct);;
このように、コンパイラは Mt.fct の型パラメーターが共変か反変かを知らないため、機能しません。ただし、モジュール署名の型宣言を次のように置き換えると:
type (-'a,'+b) fct
b が共変で反変であることをコンパイラに伝えると、今では機能します。そして、私は狡猾でうっとうしい男の子なので、コンパイラに a も共変だと言って嘘をつきました!
type (+'a,'+b) fct
でも彼は私より頭がいいし、私が嘘をついていることに気づいている。
Type declarations do not match:
type ('a, 'b) fct = 'a -> 'b
is not included in
type (+'a, +'b) fct
Their variances do not agree.
私の質問は次のとおりです:もし彼がとにかく型パラメータの分散を知っているなら、+と-を強制的に追加するのではなく、モジュールにそれを使用しないのはなぜですか. それは再び決定可能性の問題ですか?