2017-09-07 23 views
3

私はメタデータが1つのタイプパラメータとして表され、もう1つのレコードフィールドとしてメタデータが表現される2つのライブラリをインターフェースしなければなりませんでした。私はGADTを使ってアダプタを書いた。蒸留バージョンは次のとおりです。タイプファミリーと部分的な新しいタイプの違いは? (部分データ?)

{-# LANGUAGE GADTs #-} 

newtype TFId a = MkId a 
data TFDup a = MkDup !a !a 

data GADT tf where 
    ConstructorId :: GADT TFId 
    ConstructorDup :: GADT TFDup 

main = do 
    f ConstructorId 
    f ConstructorDup 

f :: GADT tf -> IO() 
f = _ 

これは機能します。 (完璧ではないかもしれませんが、歓迎ですが、それは問題ではありません)

この作業状態になるまでにはしばらく時間がかかりました。私の最初の直感は、TFIdのタイプファミリーを使用することでした。 "GADTは種類が(* -> *) -> *です。 ConstructorDupTFDupには種類* -> *があります。 「

{-# LANGUAGE TypeFamilies #-} 
type family TFId a where TFId a = a 

型コンストラクタは、同じ種類* -> *を持っていないが、GHCは明らかに同じ場所でそれを持っています:

error: …

  • The type family ‘TFId’ should have 1 argument, but has been given none
  • In the definition of data constructor ‘ConstructorId’ In the data type declaration for ‘GADT’

のでConstructorIdのために、私は次のよう* -> *型ファミリを使用することができますさて、もしそうなら...

私はそれがなぜこのような違いをもたらすのか分かりません。それを適用せずにタイプのファミリーの茎を使用していない?どうしたの?他の(より良い)方法は何ですか?

+4

はい、タイプファミリは_saturated_を使用する必要があります。つまり、宣言されたすべての引数にタイプファミリを適用する必要があります。型ファミリはコンパイル時に展開されるので、コンパイラは型のファミリの引数をすべて知っていなければならない。同じことが型同義語にも当てはまります。 –

+0

コンパイル時にもnewtypesが(よく、縮小されて)拡張されていると主張したいと思うでしょう。だから、おそらく "コンパイル時"は少し広いです。何が違うの?つまり、なぜですか? –

+0

確かに、「コンパイル時間」という言葉を少しゆるやかに使っていました。 newtypeはコード生成中に消去されます - newtypeの実行時表現はラップされた型と同じであり、どちらの方向にも自由に使えますが、 'type'sのような型検査中は展開されません。 'newtype'は他の型から離れています。タイプ同義語/ファミリーはそうではありません。 –

答えて

3

注射可能性。

type family F :: * -> * 
type instance F Int = Bool 
type instance F Char = Bool 

ここにF Int ~ F Char。しかし、

data G (a :: *) = ... 

G Int ~ G Charは決して発生しません。これらは異なるタイプであることが保証されています。

foo :: forall f a. f a -> a 

f等ユニバーサル定量において

G(単射)であることが許されなく(単射ではない)Fことが許されません。

これは推論作業を行うためのものです。 foo (... :: G Int)は、タイプIntと推定できます。 foo (... :: F Int)foo (... :: Bool)に相当し、タイプはInt、タイプはCharで、あいまいです。

foo Trueも参照してください。 GHCが私たちのためにf ~ F, a ~ Int (or Char)を選択することは期待できません。これは、すべてのタイプのファミリを見て、Boolがそれらによって生成されるかどうかを確認する必要があります。基本的に、すべてのタイプファミリを反転する必要があります。これが実行可能であったとしても、それは膨大な量の解決策を生むので、あいまいである。

関連する問題