haskell - StateT 与来自模板 haskell 的 Q monad

标签 haskell monad-transformers template-haskell state-monad

我想创建一个函数,它接受一些 Dec 类型的声明(我从 [d| ... |] 获得)并修改它们。修改将取决于以前的声明,因此我希望能够将它们存储在隐藏在 State monad 中的映射中 - 主要是我创建记录和类实例,并向它们添加以前记录中的字段。 (这样我想模仿 OOP,但这可能与我的问题无关)。我想在处理(并更改)所有声明后将计算结果拼接到代码中。

我尝试以各种可能的方式用 Q 组合 StatT,但我无法正确完成。

编辑

我的想法是创建收集类声明的函数(我知道 Haskell 不是面向对象的语言,我读了一些关于如何在 Haskell 中编码 OOP 的论文,并且我尝试使用 Template Haskell 作为小作业来实现它)。

所以我希望能够写这样的东西:

declare [d| class A a where 
                attr1 :: a -> Int
                attr2 :: a -> Int |]
declareInherit [d| class B b where
                      attr3 :: b -> Int |] ''A

这是(例如c++代码)的编码

struct A{
    int attr1;
    int attr2;
}
struct B : A {
    int attr3;
}

我想用模板 haskell 生成两条记录:

data A_data = A_data { attr1' :: Int, attr2' :: Int}
data B_data = B_data { attr1'' :: Int, attr2'' :: Int, attr3'' :: Int}

和类的实例:

instance A A_data where
    attr1 = attr1'
    attr2 = attr2'

instance A B_data where
    attr1 = attr1''
    attr2 = attr2''

instance B B_data where
    attr3 = attr3''

这就是我的 OO 编码的工作方式,但我希望能够自动生成它,而不是手动编写它。

我在声明函数中与 DecsQ 交互时遇到问题,可能我希望它存在于这样的东西中:

data Env = Env {classes :: Map.Map Name Dec }
type QS a = (StateT Env Q) a

我也有如何在 QS 中运行计算的问题。

最佳答案

Template Haskell 的一个问题是它的 API 不像大多数其他 Haskell 库那样完善。 Q monad 充满了问题:它具体化、它呈现、它管理本地名称的状态。但交错问题域从来都不是一个好主意,因为事实证明,人类一次只能思考一件事(换句话说,我们是“单核”)。这意味着将问题混合在一起是不可扩展的。这就是为什么很难推理 Q已经,并且您想在其之上添加另一个问题:您的状态。坏主意。

与任何其他问题一样,您应该通过关注点分离来解决这个问题。也就是说,您应该从主要问题域中提取较小的问题域,并单独处理每个问题域。关于 Template Haskell,有几个明显的领域:现有 AST 的具体化、它们的分析和新 AST 的呈现。对于这些域之间的通信,您可能还需要一些“通用语言”数据模型。有点想起什么,不是吗?是的,这就是 MVC。

提取的域有某些属性,您可以利用这些属性来获得好处:您只需保留在 Q 中即可。 monad for reification,渲染和分析可以在纯净的环境中完成,为您提供它的所有好处。您可以使用 unsafePerformIO . runQ 安全地净化准引号.

对于现实生活中的例子,我可以向您推荐我的一些项目,我在其中应用了这种方法:

关于haskell - StateT 与来自模板 haskell 的 Q monad,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23975681/

相关文章:

haskell - 从 TemplateHaskell 中的文件中读取模块

haskell - 模板-haskell中的单双引号/撇号有什么区别?

linux - 在 NixOS 上将 twitch lambdabot 配置为服务

haskell - 帮助解释重叠实例错误消息

list - 如何为 Haskell 的集合构建器表示法指定类型?

haskell - monad 变压器何时需要提升?

haskell - 斐波那契函数正确性的归纳证明

haskell - 在 Scotty 服务器中 fork 新线程

haskell - 如何将具有类约束的多个非标准变压器组合成一个堆栈?

haskell - 如何获取 TemplateHaskell 命名变量的文字值