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

我正在使用Haskell中嵌入的语言。 我的语言可以作为源代码打印出来,所以我创建了一个Compile类并为每个可以打印的程序元素创建一个类实例。 这样我可以在构图上转储我的代码。 在模式的概念被考虑之前,这工作得很好。

每种语言都可以在两种模式下使用(实现为类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进行表示

  • 我的一位朋友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"
    
    链接地址: http://www.djcxy.com/p/15103.html

    上一篇: Haskell : Illegal type synonym family application in instance

    下一篇: JUnit Ant task won't output to screen