データの種類、型ファミリ、および type-nats を使用するようにllvmパッケージの移植にゆっくりと取り組んできましたが、値の分類に使用される 2 つの新しい型(ConstValue
および) を削除しようとすると、小さな問題が発生しました。一貫性。Value
Value
CallArgs
引数のみを受け入れ、 aを aValue 'Variable a
にキャストする関数を提供します。各引数が または のいずれかになるように一般化したいと思います。タイプファミリを使用してこれを何らかの方法でエンコードすることは可能ですか? おそらくファンデプスで可能だと思います。Value 'Const a
Value 'Variable a
CallArgs
'Const
'Variable
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeFamilies #-}
data Const = Const | Variable
data Value (c :: Const) (a :: *)
type family CallArgs a :: *
type instance CallArgs (a -> b) = forall (c :: Const) . Value c a -> CallArgs b
type instance CallArgs (IO a) = IO (Value 'Variable a)
...コンパイルに失敗します:
/tmp/blah.hs:10:1: 不正なポリモーフィックまたは修飾型: forall (c :: Const)。値 ca 「CallArgs」の型インスタンス宣言で
次の解決策は機能しますが (従来のコードと同等)、ユーザーが each 定数をキャストする必要がありますValue
。
type family CallArgs' a :: *
type instance CallArgs' (a -> b) = Value 'Variable a -> CallArgs' b
type instance CallArgs' (IO a) = IO (Value 'Variable a)