残念ながら、Coercible (f a) (f (Decorated s a))
はGHCの現在の状態を考慮して、あなたが欲しいと思っているものです。今、s
とa
がどこにも現れないということは、何か良いことではありません - それはGHCが彼らと何をするべきか分かりません(あいまいです)!私はそれに得ることはありません...
型コンストラクタf
に供給された型パラメータのroleによっては、Coercible a b
は、またはCoercible (f a) (f b)
を意味するものではない場合があります。この場合、私たちはその役割を名目的にすることを望んでいますが、制約内でこれを表現する方法はありません(少なくとも)。私が何を意味するかを説明するには、次の2つのデータ定義を考えてみます。
{-# LANGUAGE TypeFamilies #-}
import Data.Coerce
-- type role of `a` is "representational"
data Data1 a = Data1 a
-- type role of `a` is "nominal"
data Data2 a = Data2 (TypeFunction a)
type family TypeFunction x where
TypeFunction Bool = Char
TypeFunction _ =()
を次に、それが真の間Coercible a b
はCoercible (Data1 a) (Data1 b)
を伴うこと、それはないがCoercible (Data2 a) (Data2 b)
を伴うん。 、このコンクリートを作るGHCiの中に上記をアップロードするには、その後、試してみてください。
ghci> newtype MyInt = My Int
ghci> let c1 = coerce :: (Data1 MyInt) -> (Data1 Int)
ghci> let c2 = coerce :: (Data2 MyInt) -> (Data2 Int) -- This doesn't work!
は残念ながら、型変数の役割は具象的であることを強制する組み込みの制約ベースの方法はありません。エドワード・Kmett has doneのような独自のクラスを作ることができますが、GHCはCoercible
のクラスインスタンスのように、これらのクラスのインスタンスを自動的に作成しません。
これは、彼らが、これは実際に今日の事だった場合
instance (Representational f, Coercible a b) => Coercible (f a) (f b)
のようなものを持っている可能性がCoercible
のためのように生成されたインスタンスを持つクラスRepresentational f
を持つ可能性を議論this Tracのチケット、あなたが必要となるすべてにつながりましたあなたの制約内ではRepresentational f
になります。さらに、リチャード・アイゼンバーグがチケットで見ているように、のf a
には、任意の合理的なファンクタf
の表現的役割があることが分かります。それでFunctor f
の上に何の制約も必要ないかもしれないので、Representational
はFunctor
のスーパークラスになる可能性があります。
Here is a good discussion of the current limitations of roles.
'myFunction'すでにコンパイルされませんので、'のCtxがS' fancyFunction' 'から生じる、関数の型に(あなたが指摘したように)タイプ' S'は言及されていないので、あいまいな型のエラーになります( 'fancyFunction。undefined'でもこのようなエラーが出ます)。いずれにしても、あなたは操作上のアイデンティティである関数 '(Functor f、Coercible ab)=> fa - > fb'が必要な場合があります。この場合、[profunctors](https://hackage.haskell)に興味があります。これはGHCがあなたに伝えるように、一般的に「安全でない」操作を使用します.. – user2407038
「NB:私たちは何を知ることができませんか? roleに '' f ''のパラメータがあるので、関連しないあいまいな型のエラーを修正した場合(例えば 'Ctx s'の制約を取り除くなどして)、その役割が名目上のものであると仮定しなければなりません。型変数の役割について話す方法はありません。これは既知の制限です。 – user2407038
私はこれを回避する方法はないと確信しています。問題は、あなたがしたいことは 'f'の役割に依存して実行できるかできないかということです。 [This](https://ghc.haskell.org/trac/ghc/ticket/9123)のチケットがさらに詳細になります。 [こちら](https://github.com/ekmett/roles/blob/master/src/Data/Roles.hs)は、Edward Kmettの代替アプローチの1つです。 – Alec