はスニペットタイプ型クラスを使用して統一していないと型家族
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
import Data.Proxy
monadify' :: forall m sig. (Monad m, Sig sig) => Proxy sig -> Monadify m sig
monadify' p = monadify p (return() :: m())
type family Monadify f a where
Monadify f (a -> r) = a -> Monadify f r
Monadify f a = f a
class Sig sig where
monadify :: Monad m => Proxy sig -> m() -> Monadify m sig
を考えてみましょう私はインスタンスを与えられていないましたが、使用例はf :: Int -> String -> Bool, monadify' f :: Int -> String -> IO Bool
だろう。
これは、次のエラーメッセージが表示されてです。TypeCheckに失敗:
Couldn't match expected type ‘Monadify m sig’
with actual type ‘Monadify m0 sig0’
NB: ‘Monadify’ is a type function, and may not be injective
The type variables ‘m0’, ‘sig0’ are ambiguous
In the ambiguity check for the type signature for ‘monadify'’:
monadify' :: forall (m :: * -> *) sig.
(Monad m, Sig sig) =>
Monadify m sig
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
In the type signature for ‘monadify'’:
monadify' :: forall m sig. (Monad m, Sig sig) => Monadify m sig
直感的に、私は(私はしたい、それはです。TypeCheckべきであると言うだろうが、GHCは単射として注釈されていないタイプの家族、によって混乱してしまいます下位互換性のためではない)。それはm()
とProxy
からプリイメージを回復することができます。だから私は本当にここで何が問題なのか分かりません。
編集:エラーメッセージが示すように
、私は私の場合、すべての問題を修正した、AllowAmbiguousTypes
に投げることができました。しかし、私はその拡張機能を使用することの結果を知らないだけでなく、なぜ私の例が型チェックをしないのかを知っています。
Monadify m sig
を一元化しようとするユニファイアと関係があると感じて、sig
とm
が同一であることを証明できないと推測します。ユニファイナーは渡された引数を見て、それらが同一であることを知る必要がありましたが、それでAllowAmbiguousTypes
が役立つかもしれません。
ああ、もちろん。私は質問を間違って尋ねたので、実際には 'sig'のプロキシを実際に渡しています(私の実際の使用例では' Tagged')。これは欠けている注入性、すなわちFunDep '(Monadify m sig)sig - > m 'が成立するはずである。その知識で、 'AllowAmbiguousTypes'を使うのは安全ですか?上記の私の編集を参照してください。 –
具体的には、 'AllowAmbiguousTypes'のどれかが呼び出しモジュールに漏れているかどうかを知りたいので、タイプエラーを見つけ出すのに苦労します。私はそれがGHCIの私の具体的な使い方についてはうまく動作することを知っていますが、それが一般的なケースかどうかは不明です。 –
また、 'family monadify f a = r | r a - > f where ... 'はサポートされていませんが、' - > 'のLHSでは単一の' r 'だけが許されます。それゆえ、より少ない注入特性を述べることさえできない。 – chi