【发布时间】:2017-07-20 15:09:18
【问题描述】:
我正在用 Haskell 编写一段代码,其中有一行代码是这样的:
addElement :: [a] -> a -> [a]
addElement list elem = list ++ [elem]
我需要(或至少,我认为如此)这样的函数,用于在我正在实现的图形数据结构的顶点列表中添加新顶点。现在,我可以如下调用这个函数
newlist = addElement oldlist elem
一切正常。但是,如果我写
mylist = addElement mylist elem
然后在调用终止后尝试对 mylist 执行任何操作(确实如此),我进入一个无限循环,如果我理解正确,这是由于 Haskell 的惰性评估或类似的东西(mylist如果我做对了,会扩展到addElement (addElement ... elem) elem?)。
这对于我的特定实现当然是不利的,因为就我的目的而言,我现在每次需要向列表中添加元素时都必须创建新列表。那么如何制作一个按我想要的方式工作的元素添加功能呢?
【问题讨论】:
-
mylist = addElement mylist elem这不是作业,而是等式。 Haskell 没有更新。在上下文中展示您的尝试。您是如何尝试构建 mylist 的? -
嗯,我基本上是先运行
mylist = [],然后,比如说mylist = addElement mylist 3。第二次调用相当于mylist = mylist ++ [3]。例如,如果我在 ghci 中键入id mylist,则什么也不会发生,我会陷入困境。那么我是否应该认为在 Haskell 中不可能有一个函数addElement最终会导致id mylist导致[3]? -
不,请显示您尝试构建 mylist 的整个函数。
-
如果你不需要按特定顺序构建列表,那么在前面添加一个元素就是解决方案(这是一个 O(1) 操作)。即使您需要这个特定的顺序,以相反的顺序构建列表并最终将其反转一次可能会更便宜。
标签: debugging haskell recursion infinite-loop lazy-evaluation