上帝我讨厌“代码气味”这个词,但我想不出更准确的说法。
我在业余时间为Whitespace设计高级语言和编译器,以了解编译器构造、语言设计和函数式编程(编译器是用 Haskell 编写的)。
在编译器的代码生成阶段,我必须在遍历语法树时维护“状态”数据。例如,在编译流控制语句时,我需要为要跳转到的标签生成唯一名称(从传入、更新和返回的计数器生成的标签,并且不得再次使用计数器的旧值)。另一个例子是当我在语法树中遇到内联字符串文字时,需要将它们永久转换为堆变量(在 Whitespace 中,字符串最好存储在堆中)。我目前正在将整个代码生成模块包装在 state monad 中来处理这个问题。
有人告诉我,编写编译器是一个非常适合函数式范例的问题,但我发现我设计它的方式与我在 C 中设计它的方式非常相似(你真的可以用任何语言编写 C - 甚至带有状态单子的 Haskell)。
我想学习如何在 Haskell 中思考(而不是在函数范式中)——而不是在带有 Haskell 语法的 C 中。我真的应该尝试消除/最小化 state monad 的使用,还是它是一种合法的功能性“设计模式”?