【问题标题】:If you can't change a variable's value in Haskell, how do you create data structures?如果你不能在 Haskell 中改变变量的值,你如何创建数据结构?
【发布时间】:2010-12-20 18:04:31
【问题描述】:

根据标题。

我有以下代码可以创建一个二叉搜索树,但是如果我想通过用户输入动态创建和更改它,如果我无法更改 haskell 中变量的值,我该怎么做?!?

find :: (Ord a) => Node a -> a -> Bool
find (Node val left right) s
    | s == val      = True
    | s < val       = find left s
    | s > val       = find right s

find Empty s = False

data Node a = Node a (Node a) (Node a)
              | Empty

myTree = Node "m"   (Node "a" Empty Empty)
                    (Node "z" Empty Empty)

提前致谢!

【问题讨论】:

    标签: variables data-structures haskell constants


    【解决方案1】:

    您分配了一个新的树节点,而旧的节点仍然存在。这种技术需要一个非常好的分配器,但它支持各种漂亮的设备,因为程序的其他部分仍然可以访问旧节点。对于某些涉及所谓“持久数据结构”的推测算法或其他技巧来说,这是天赐之物。

    最终你为你的树分配了一个新的根,然后呢?正如 Dario 所说,您将它作为参数传递给函数(而不是将其存储在全局变量中)。

    所以

    • 在堆上分配的结构中字段的突变变成在堆上分配新结构。

    • 全局变量的变异变成了将参数传递给函数

    有时将 C 中的全局变量集合放入堆上分配的对象中也是有意义的。


    附:如果你真的想要,你可以在 Haskell 中拥有可变的全局变量。毕竟,它是世界上最好的命令式编程语言(根据 Wadler 或 Peyton Jones 的说法,我忘记了是谁)。但如果你问这个问题,你真的不想问。然而。

    【讨论】:

      【解决方案2】:

      纯函数式数据结构背后的想法是计算新值而不是更改它们,并将它们(递归地)传递到参数中,而不是全局存储它们。

      所以给定一个函数

      insert :: Ord a => Node a -> a -> Node a
      

      您的程序可能如下所示

      -- Let the user enter k values that are stored in a tree structure
      addTreeItems :: Int -> Node Int -> IO (Node Int)
      addTreeItems 0 tree = return tree
      addTreeItems k tree = do
          putStr "Enter new item: "
          item <- readLn
          addTreeItems (k - 1) (insert tree item) -- Recursively pass the tree
      
      main = do
          tree <- addTreeItems 10 Empty
          -- ...
      

      使用一元辅助函数,这可以简化为

      (foldl insert Empty) `liftM` (sequence $ replicate k (putStr "Enter new item: " >> readLn))
      

      如果您想更新某个位置的值,您将需要更高级的数据结构,例如 zipper,但仍然纯粹是功能性的!

      【讨论】:

      • 感谢您的回复。我的意思不是要密集,但给出的例子我似乎仍然有同样的问题。您将进入“插入树项”,树是一个连接了左右节点的节点,可能为“空”或不“空”。第一次调用 addTreeItems 时,它会再次调用由“插入树项”返回的树,该树只有一个节点,可能有两个空分支。第二次递归将此根节点与一个新项目一起传递给插入,但是如果节点的分支无法更改(在这种情况下为空),该项目如何添加到节点?谢谢!
      • 没关系,我太密集了,忘记了我需要创建一棵全新的树,我现在已经接近我自己的解决方案了。
      【解决方案3】:

      达里奥给出了一个很好的直接答案。如果您想了解更深入的信息,请参阅 Chris Okasaki 撰写的 Purely Functional Data Structures,这是一本关于该主题的整本书。我自己买的,但遗憾的是,我没有时间尝试这些想法。

      【讨论】:

      • 这本书是根据他的博士学位改编的。论文,所以如果你买不起,你可以细读thesis
      • @Don Wakefield 谢谢你。老实说,任何你找到昨天没有的参考资料或知识的日子都是美好的一天。非常感谢您引用该论文!
      猜你喜欢
      • 2019-02-19
      • 1970-01-01
      • 1970-01-01
      • 2018-03-30
      • 1970-01-01
      • 1970-01-01
      • 2010-09-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多