Haskellプラットフォームだけで多数の重複するモジュールを持つジェネリックライブラリがいくつかありますが(、、、、syb
)Data.Typeable
、非常Data.Data
にGHC.Generics
基本的なジェネリックプログラミングタスクで問題が発生しています。
同じ形状のタイプ間で変換できるようにしたい、つまり、同型タイプ間で多形の型付き変換関数が必要です。これは、基本的に、このペーパーの最後(PDF)で提供されているインデックス付きタイプファミリーについて説明しています。
ボイラープレートを廃棄することではなく、合計と製品の抽象化を中心に新しいライブラリを構築できるようにすることに関心があります。
以下の質問は、GHC.Generic
私が必要としているものに最も近いと思った点ですが、他の解決策も歓迎します。
次の2種類は同じ形です
data Pair = Pair Char Int deriving (Generic, Show)
data Pair2 = Pair2 Char Int deriving (Generic, Show)
GHC.Genericsを使用してそれらの間で値を変換したいと思います。以下は、すべてのファントムパラメータおよびその他のナンセンスのためにタイプチェックに失敗します。
f :: Pair -> Pair2
f = to . from
最終的には、任意の(または他のクラスがこれをサポートできる)インスタンスfromInteger
のポリモーフィックな戻り値を持つそれに類似した関数が必要です。Generic
私は次のようなものを探していると思いGHC.Generics
ます:
--class:
type family NormalForm a
class ToGeneric a where
to :: a -> NormalForm a
class FromGeneric b where
from :: NormalForm b -> b
--examples:
data A = A Char Int deriving Show
data B = B Char Int deriving Show
type instance NormalForm A = (Char,Int)
instance ToGeneric A where
to (A a b) = (a,b)
instance FromGeneric A where
from (a,b) = A a b
type instance NormalForm B = (Char,Int)
instance ToGeneric B where
to (B a b) = (a,b)
instance FromGeneric B where
from (a,b) = B a b
-- the function I'm looking for
coerce :: (ToGeneric a, FromGeneric b, NormalForm a ~ NormalForm b)=> a -> b
coerce = from . to
上記で私たちは私が望むすべてを行うことができます:
*Main> (coerce $A 'a' 1) :: B
B 'a' 1
*Main> (coerce $A 'a' 1) :: A
A 'a' 1
編集:f
これは、実際には、ネイサンハウエルの関数が以下でどのように機能するように見えるかです。
質問
これは、現在haskellプラットフォームにあるライブラリで行うことができますか?
そうでない場合は、 THに頼らずに、などの既存の
deriving
メカニズムを活用するライブラリを定義できますか?Generic
Data