将无状态函数转换为有状态函数

时间:2015-10-13 18:54:47

标签: haskell

我目前正在Haskell中编写一个编译器作为玩具项目,我有一个函数可以使用签名进行状态转换:

transform :: (Exp -> m Exp) -> Exp -> m Exp

这允许我在其上实现以下类型的操作:

  • 累积结果,例如获取在表达式中调用的函数列表。
  • 可以返回错误的转换,例如类型注释,它返回带有类型的AST或描述类型问题的错误。
  • 依赖于先前完成的转换的转换,例如在生成测试输入时对变量名进行重复数据删除。
  • 我希望它也能让我以优雅的方式进行无状态计算。

但不知何故,即使这一定非常简单,我仍然坚持根据上述具有以下特征的转换方法创建无状态映射函数:

map :: (Exp -> Exp) -> Exp -> Exp

我宁愿不再对如何遍历地图中的子项进行相同的逻辑,而是在变换的基础上实现它。

1 个答案:

答案 0 :(得分:5)

如果这是transform的实际类型,那么您应该可以执行以下操作:

Control.Monad.Identity> :t transform
transform :: (Exp -> m Exp) -> Exp -> m Exp
Control.Monad.Identity> :t \f -> runIdentity . transform (Identity . f)
\f -> runIdentity . transform (Identity . f)
  :: (Exp -> Exp) -> Exp -> Exp

但是,您可能在m上有其他约束而未在可能排除Identity的问题中写入。