Haskell:实例中的非法类型同义词系列应用程序

BoldizsárNémeth

我正在使用Haskell中嵌入的语言。我的语言可以作为源代码打印出来,因此我创建了一个Compile类,并为每个可以打印出的程序元素制作了一个类实例。这样一来,我就可以合成代码了。在考虑模式概念之前,这种方法效果很好。

每种语言都可以在两种模式下使用(实现为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用于表示
BoldizsárNémeth

我的一个朋友ZoltánKelemen给我发送了一个解决方案。他使用包装器类来封装指定语言的程序元素。这样,他从实例头中消除了类型族应用程序,而没有必要的额外开销。

我也在寻找其他解决方案。

{-# LANGUAGE TypeFamilies, MultiParamTypeClasses, FlexibleInstances, UndecidableInstances #-}
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 :: * -> *

-- wrapper classes for program elements of Lang1
data Lang1A m = WrapperA (ElemA Lang1 m)
data Lang1B m = WrapperB (ElemB Lang1 m)

-- 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 (Lang1A m) where  
  comp (WrapperA e) = "A"
-- AND HERE
instance Compile (Lang1B m) where  
  comp (WrapperB e) = "B"

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章