haskell - 如何在函数式编程中为AST节点生成稳定的id?

标签 haskell functional-programming immutability abstract-syntax-tree

我想将一个特定的 AST 节点替换为另一个节点,并且这个替换的节点是由交互式用户输入指定的。

在非函数式编程中,可以使用可变数据结构,并且每个AST节点都有一个对象引用,因此当我需要引用特定节点时,可以使用这个引用。

但是在函数式编程中,不建议使用IORef,所以我需要为每个AST节点生成id,并且我希望这个id稳定,这意味着:

  1. 当节点不改变时,生成的id也不会改变。
  2. 当子节点更改时,其父节点的 id 不会更改。

并且,为了明确它是一个 id 而不是哈希值:

  • 对于两个不同的子节点,它们比较相等,但对应表达式的不同部分,它们应该具有不同的 id。
  • 那么,我应该怎么做才能解决这个问题?

    最佳答案

    也许您可以使用从根到节点的路径作为该节点的 id。例如,对于数据类型

    data AST = Lit Int
             | Add AST AST
             | Neg AST
    

    你可以有类似的东西

    data ASTPathPiece = AddGoLeft
                      | AddGoRight
                      | NegGoDown
    
    type ASTPath = [ASTPathPiece]
    

    这满足条件 2 和 3,但遗憾的是,它通常不满足条件 1。例如,如果您在先前位置插入节点,列表中的索引将会更改。

    如果您要将 AST 渲染为另一种格式,也许您可​​以在结果节点中添加隐藏属性,以识别哪个 ASTPathPiece 通向它们。向上遍历结果节点到根可以让您重建 ASTPath

    关于haskell - 如何在函数式编程中为AST节点生成稳定的id?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50960866/

    相关文章:

    haskell - GHC的语言扩展: "Arrows"?的源代码在哪里

    haskell - Haskell 中 Pointfree 风格的元素数量

    haskell - 帮助运行 Yesod 开发服务器?

    scala - scala 中的逆变

    javascript - redux:使用不可变方法修改数组中对象的属性的性能。优点和缺点

    java - Is Class<T> immutable in Java,也就是 Class<T> 是 HashMap 的安全键吗?

    Haskell 堆栈与全局 ghc

    scala - 如何将值用作目标函数的参数

    functional-programming - 如何判断一个序列是否递增?

    c# - 不变性对非并行应用程序有用吗?