a
タイプのいくつかの値関数の最適な値を計算することを仕事とする関数がありますa -> v
type OptiF a v = (a -> v) -> a
次に、値の値を使用する別の関数と一緒にそのような関数を格納するコンテナーがあります。
data Container a = forall v. (Ord v) => Cons (OptiF a v) (a -> Int)
のインスタンスであることを除いて、 type の関数を実装する人は誰でもOptiF a v
の詳細に悩まされるべきではないという考えです。v
Ord
そのため、そのような値関数とコンテナーを取る関数を作成しました。を使用するOptiF a v
と、最適な値 wrt が計算val
され、コンテナーのresult
関数にプラグインされます。
optimize :: (forall v. (Ord v) => a -> v) -> Container a -> Int
optimize val (Cons opti result) = result (opti val)
ここまでは順調ですが、 を呼び出すことはできませんoptimize
。
callOptimize :: Int
callOptimize = optimize val cont
where val = (*3)
opti val' = if val' 1 > val' 0 then 100 else -100
cont = Cons opti (*2)
コンパイルしません:
Could not deduce (v ~ Int)
from the context (Ord v)
bound by a type expected by the context: Ord v => Int -> v
at bla.hs:12:16-32
`v' is a rigid type variable bound by
a type expected by the context: Ord v => Int -> v at bla.hs:12:16
Expected type: Int
Actual type: Int
Expected type: Int -> v
Actual type: Int -> Int
In the first argument of `optimize', namely `val'
In the expression: optimize val cont
行 12:16-32 はoptimize val cont
です。
この場合、存在型を誤解していますか? それが望むものは何でも期待できるという意味forall v
の宣言の中にありますか? それとも、それ以外には何も期待できないということですか?optimize
optimize
a -> v
v
optimize
a -> v
Ord v
私が欲しいのは、後でプラグインしたいので、OptiF a v
がどの にも固定されていないことです。私が課したい唯一の制約は. 存在型(または何でも)を使用してそのようなものを表現することさえ可能ですか?v
a -> v
Ord v
optimize
と同様のシグネチャを持つ関数を提供する追加の型クラスでそれを達成することができましたが、OptiF a v
それは高階関数を使用するよりもずっと醜く見えます。