Bol*_*eth 7 haskell types typeclass type-families
我正在使用嵌入在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"
Run Code Online (Sandbox Code Playgroud)
我知道类型同义词系列不适用于类,所以我正在寻找另一种解决方案.
我知道的可能的解决方案(但不想使用):
comp函数.NamedMode用于表示我的一个朋友 Zolt\xc3\xa1n Kelemen 给我发了一个解决方案。他使用包装类来封装指定语言的程序元素。通过这种方式,他从实例头中消除了类型系列应用程序,而没有超出必要的开销。
\n\n我也在寻找其他解决方案。
\n\n{-# LANGUAGE TypeFamilies, MultiParamTypeClasses, FlexibleInstances, UndecidableInstances #-}\nclass Compile a where\n comp :: a -> String\n\n-- common elements in all languages\ndata ElemA l m = ElemA (ElemB l m)\ndata ElemB l m = ElemB\n\nclass Lang l where\n -- language-specific elements\n data Instructions l :: * -> *\n\n-- wrapper classes for program elements of Lang1\ndata Lang1A m = WrapperA (ElemA Lang1 m)\ndata Lang1B m = WrapperB (ElemB Lang1 m)\n\n-- common modes for all languages\nclass Mode l m where\n type MElemA l m :: *\n type MElemB l m :: *\n\n-- mode with normal program elements\ndata SimpleMode\ninstance Mode l SimpleMode where\n type MElemA l SimpleMode = ElemA l SimpleMode\n type MElemB l SimpleMode = ElemB l SimpleMode\n\n-- a mode where each program element can be replaced with a string\ndata NamedMode\ninstance Mode l NamedMode where\n type MElemA l NamedMode = Either String (ElemA l NamedMode)\n type MElemB l NamedMode = Either String (ElemB l NamedMode)\n\n-- definition of Lang1 language\ndata Lang1\ninstance Lang Lang1 where\n data Instructions Lang1 m \n = Add (MElemA Lang1 m) (MElemA Lang1 m) (MElemA Lang1 m)\n | Mul (MElemA Lang1 m) (MElemA Lang1 m) (MElemA Lang1 m)\n -- | ...\n\n-- dumping the source code of Lang1 langauge\n\n-- ILLEGAL TYPE SYNONYM FAMILY APPLICATION HERE\ninstance Compile (Lang1A m) where \n comp (WrapperA e) = "A"\n-- AND HERE\ninstance Compile (Lang1B m) where \n comp (WrapperB e) = "B"\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
1241 次 |
| 最近记录: |