Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 如何处理';丢失对象';在函数式编程中?_Haskell_Functional Programming - Fatal编程技术网

Haskell 如何处理';丢失对象';在函数式编程中?

Haskell 如何处理';丢失对象';在函数式编程中?,haskell,functional-programming,Haskell,Functional Programming,我和Haskell一起工作,我在编写程序时遇到的一个大问题是,当我想对一个对象做一些事情时,我的程序忘记了我以前用它做过的一切。例如,当您使用zipper实现树时,为了能够知道您在树上的位置,每次移动时,您必须将所有节点存储在路径的左侧和右侧。类似地,如果我想编写一个简单的深度优先搜索,我觉得我必须保留另一个单独的记录,记录我访问过哪些顶点,以及下一个要访问哪些顶点,以免我返回到一个旧顶点而忘记我去过的地方 我的问题是:这种情况持续发生吗?为数据编写函数程序的“正确”方法是否改变了您过去所做的一

我和Haskell一起工作,我在编写程序时遇到的一个大问题是,当我想对一个对象做一些事情时,我的程序忘记了我以前用它做过的一切。例如,当您使用zipper实现树时,为了能够知道您在树上的位置,每次移动时,您必须将所有节点存储在路径的左侧和右侧。类似地,如果我想编写一个简单的深度优先搜索,我觉得我必须保留另一个单独的记录,记录我访问过哪些顶点,以及下一个要访问哪些顶点,以免我返回到一个旧顶点而忘记我去过的地方

我的问题是:这种情况持续发生吗?为数据编写函数程序的“正确”方法是否改变了您过去所做的一切

data SimpleTree a = Leaf a | Branch a (SimpleTree a) (SimpleTree a)

dfs :: Eq a => a -> SimpleTree a -> Bool
dfs val (Leaf v2) = v2 == val
dfs val (Branch v2 t2 t3) = v2 == val
                            || dfs val t2
                            || dfs val t3
然后:

我的DFS算法没有显式地携带访问过的树节点列表


为您的结构编写算法的正确方法取决于您的结构,但是没有通用的要求您在访问的节点列表中拖动。(拉链确实有这一要求——这对它们的工作方式至关重要。)

在这种普遍性中很难说清楚(什么是变化的数据?)-例如,编写处理树的算法的常用方法是编写递归函数(树本身通常是递归定义的)-在这里,您不必记住路径,因为递归会帮您记住路径-但是,如果您想在此类结构中移动并在本地编辑它们,则可以使用Zipper。记住哪些节点已被访问是dfs的一部分(以及任何其他搜索)。当然,您可以将这些信息烘焙到图形中,但这主要是为了使图形结构更加复杂,从而获得通常可以忽略不计的性能增益。具体而言,对于图形,请检查归纳图和。我最近写了一个答案,关于哪一个适合深度优先搜索。有关更多详细信息,请查看我关于的博客文章。您的“dfs”只起作用,因为您的图形是有向树。要遍历一个有向树,需要重新访问以前的节点,这是不完全愚蠢的。对于非循环图,您必须以某种方式记住以前访问过的节点。我将问题解释为“是否始终需要在Haskell中存储所有数据结构的访问过的节点”,并证明答案是“否”。对于非非循环图,不管语言选择如何,您都需要跟踪访问的节点,但这是假设一组与所提到的问题不同的细节。OP似乎隐含地谈论了图DFS。他们似乎还认为,这种跟踪路径的需求源于函数式编程的局限性,而不是与他们正在处理的特定问题有关(并且您不需要在非函数式语言的图形DFS实现中跟踪访问节点)。
*Main> let sampleTree = Branch 5 (Branch 4 (Leaf 3) (Leaf 2)) (Leaf 6)
*Main> map (\n -> dfs n sampleTree) [1..7]
[False,True,True,True,True,True,False]