私はHaskellに埋め込まれた言語で作業しています。私の言語はソースコードとして印刷することができるので、Compile
クラスを作成し、印刷可能なすべてのプログラム要素に対してクラスインスタンスを作成しました。そうすれば、コードを構成的にダンプすることができます。これは、モードの概念が考慮される前にうまくいきました。Haskell:インスタンスの不正な型同義語ファミリアプリケーション
各言語は2つのモード(クラスMode
のインスタンスとして実装)で使用できます。シンプルモードではすべて正常です。名前付きモードでは、多くのプログラム要素を文字列で置き換えることができます。 (マクロ定義のように機能します)
すべての表現を型安全に保ちたいと思います。したがって、異なるランゲージや異なるモードのプログラム要素を混在させることはできません。
問題は次のとおりです。モードに関係なく言語をどのようにダンプするのですか?
{-# LANGUAGE TypeFamilies, MultiParamTypeClasses, FlexibleInstances #-}
class Compile a where
comp :: a -> String
-- common elements in all languages
data ElemA l m = ElemA (ElemB l m)
data ElemB l m = ElemB
class Lang l where
-- language-specific elements
data Instructions l :: * -> *
-- common modes for all languages
class Mode l m where
type MElemA l m :: *
type MElemB l m :: *
-- mode with normal program elements
data SimpleMode
instance Mode l SimpleMode where
type MElemA l SimpleMode = ElemA l SimpleMode
type MElemB l SimpleMode = ElemB l SimpleMode
-- a mode where each program element can be replaced with a string
data NamedMode
instance Mode l NamedMode where
type MElemA l NamedMode = Either String (ElemA l NamedMode)
type MElemB l NamedMode = Either String (ElemB l NamedMode)
-- definition of Lang1 language
data Lang1
instance Lang Lang1 where
data Instructions Lang1 m
= Add (MElemA Lang1 m) (MElemA Lang1 m) (MElemA Lang1 m)
| Mul (MElemA Lang1 m) (MElemA Lang1 m) (MElemA Lang1 m)
-- | ...
-- dumping the source code of Lang1 langauge
-- ILLEGAL TYPE SYNONYM FAMILY APPLICATION HERE
instance Compile (MElemA Lang1 m) where
comp _ = "A"
-- AND HERE
instance Compile (MElemB Lang1 m) where
comp _ = "B"
タイプ同義語ファミリがクラスでうまく動作しないことがわかっているので、別の解決策を探しています。私の知る(ただし、使用したくない)
考えられる解決策:
- 使用する複数の機能の代わりに、単一多型
comp
機能。 - のみを使用し
NamedMode
表現
この他の質問との類似点に言及してくれてありがとう:http://stackoverflow.com/questions/2590495/problem-when-mixing-type-classes-and-type-families?rq=1 –
はでしたデータの代わりにnewtypeを使用しました - いいえ? – lynnard