タイプファミリーで式を表現しようとしていますが、私が望む制約を記述する方法を見つけられないようで、それができないと感じ始めています。ここに私のコードです:タイプ制約を持つHaskellタイプのファミリーインスタンス
class Evaluable c where
type Return c :: *
evaluate :: c -> Return c
data Negate n = Negate n
instance (Evaluable n, Return n ~ Int) => Evaluable (Negate n) where
type Return (Negate n) = Return n
evaluate (Negate n) = negate (evaluate n)
これはすべてコンパイルされますが、正確に私が望むものを表現していません。 Negate
インスタンスの制約では、Evaluable
の表現では、Negate
内の式の戻り値の型は、(Return n ~ Int
)でなければならないので、私はそれにネゲートを呼び出すことができますが、それはあまりにも制限的です。戻り値の型は実際にはNum
型クラスのインスタンスである必要があります。このクラスのクラスはnegate
です。そのようにしてDouble
s、Integer
s、またはNum
の他のインスタンスも否定することができ、ただInt
ではありません。 Num
は型クラスであるとReturn n
がタイプですので、しかし、私はちょうど代わり
Return n ~ Num
を書き込むことはできません。 Return n
は型ではない型変数であるので、私はまた、代わりに
Num (Return n)
を置くことはできません。
私はハスケルでも可能なことをしようとしていますか?もしそうでなければ、それはすべきか、あるいは私はそれの背後にあるいくつかの理論を誤解していますか?私はJavaのような制約を加えることができるように感じる。この質問がもっと分かりやすいかどうか私に教えてください。
編集:ありがとうございました。返信は助けになり、私が疑ったものになっています。型チェッカーはUndecidableInstancesなしで何をしたいのかを処理できないようですので、私の質問は、私が本当に決めることができないものですか?それはHaskellのコンパイラですが、それは一般的ですか?つまり、より高度な型チェッカに決定可能な「戻り値nがNumのインスタンスであることを確認する」という意味の制約が存在する可能性がありますか?
btw、GHCは、 'FlexibleContexts'または何か、試行錯誤の過程で?私はそれが本当に確信しているからです - ちょうどサイドノートは_ "これはHaskellでも可能ですか?" –