2016-09-16 3 views
3

を強制可能に適用されます。その根拠は、coerceidのように振る舞い、ファンクタの法則の1つはfmap id = idです。強制する方法ファンクタは、以下のHaskellのコードを考えてみましょう引数

これを行うには、Coercible (f a) (f (Decorated s a))をコンテキストに追加するしかありませんが、他の場所では参照されていないsが参照されます。さらに悪いことに、aが汎用型でバインドされている場合、私はその制約を表現できません。 coerceを使用してf af (Decorated s a)の間で変換できるようにするには、fという言葉で表現できる制約はありますか?

これは、コンパイラがfがファンクタであるという事実から独立していますか?もしそうなら、それはバイフォンター、トラバーサブル、ビットラヴァラブルでも使えますか?

+0

'myFunction'すでにコンパイルされませんので、'のCtxがS' fancyFunction' 'から生じる、関数の型に(あなたが指摘したように)タイプ' S'は言及されていないので、あいまいな型のエラーになります( 'fancyFunction。undefined'でもこのようなエラーが出ます)。いずれにしても、あなたは操作上のアイデンティティである関数 '(Functor f、Coercible ab)=> fa - > fb'が必要な場合があります。この場合、[profunctors](https://hackage.haskell)に興味があります。これはGHCがあなたに伝えるように、一般的に「安全でない」操作を使用します.. – user2407038

+1

「NB:私たちは何を知ることができませんか? roleに '' f ''のパラメータがあるので、関連しないあいまいな型のエラーを修正した場合(例えば 'Ctx s'の制約を取り除くなどして)、その役割が名目上のものであると仮定しなければなりません。型変数の役割について話す方法はありません。これは既知の制限です。 – user2407038

+1

私はこれを回避する方法はないと確信しています。問題は、あなたがしたいことは '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

答えて

4

残念ながら、Coercible (f a) (f (Decorated s a))はGHCの現在の状態を考慮して、あなたが欲しいと思っているものです。今、saがどこにも現れないということは、何か良いことではありません - それは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 bCoercible (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の上に何の制約も必要ないかもしれないので、RepresentationalFunctorのスーパークラスになる可能性があります。

Here is a good discussion of the current limitations of roles.

関連する問題