8

Haskell に組み込まれた言語を扱っています。私の言語はソース コードとして印刷できるので、Compileクラスを作成し、印刷できるすべてのプログラム要素のクラス インスタンスを作成しました。そうすれば、コードを構成的にダンプできます。モードの概念が考慮される前に、これはうまくいきました。

各言語は 2 つのモードで使用できます ( class のインスタンスとして実装されます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表現のみに使用
4

1 に答える 1