如何定义搜索树上的地图和折叠?

发布于 2024-09-29 00:12:33 字数 415 浏览 2 评论 0原文

我有一个搜索树,其定义为:

data (Ord a) => Stree a = Null | Fork (Stree a) a (Stree a) deriving Show 

我必须定义两个函数,mapStree:

mapStree :: (Ord b, Ord a) => (a -> b) -> Stree a -> Stree b

和foldStree:

foldStree :: (Ord a) => (b -> a -> b -> b) -> b -> Stree a -> b

我不完全理解发生了什么,也不知道如何做到这一点。

I have a search tree that's defined as:

data (Ord a) => Stree a = Null | Fork (Stree a) a (Stree a) deriving Show 

and I have to define two functions, mapStree:

mapStree :: (Ord b, Ord a) => (a -> b) -> Stree a -> Stree b

and foldStree:

foldStree :: (Ord a) => (b -> a -> b -> b) -> b -> Stree a -> b

I don't fully understand what's going on and don't know how to do this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

锦欢 2024-10-06 00:12:33

您希望地图将函数应用于树所带有的任何标签。这意味着使用作为转换函数给出的函数,将 a 的任何出现更改为 b 的出现。

为此,您需要弄清楚如何处理 Stree 的每个可能的构造函数。现在,Null 很简单——它一开始就不会依赖于a。更棘手的是如何使用Fork。在 Fork 中,有一个 a 和另外两个 Stree,因此您需要采用 a ->; 的函数。 b 并采取 Stree a ->街b。对于前者,mapStree 的调用会为您提供一个函数,对于后者,mapStree f 具有您需要的调用签名(通过部分应用!)。

对于 foldStree,您有一些累积类型 b 和标签类型 a,以及一个采用两个 b< 类型值的累积函数/code> 和 a 类型的值并生成 b。这很有帮助,至少是因为该累积函数反映了树中任何给定 Fork 处可能拥有的内容:通过递归,您可以假设您从左侧和右侧 Stree< 都获得了结果/code>,只需将它们与中间的 a 值组合起来,即可给出新的 b 值来进行递归。 foldStreeb 参数为您提供了足够的标准值,以便通过获取每个叶子的值来开始整个事情。

因此,您的 foldStree 还需要在可能的构造函数上定义:选择 Null 值的参数,然后选择 Fork 的参数值,在使用参数组合函数组合所有内容之前,它需要递归到两个 Stree 值。

请在评论中澄清这是否足以帮助您解决问题:我(和这里的许多其他人)可以澄清,但希望您学习如何做到这一点,而不是仅仅交给您代码。

You want your map to apply a function to any label carried by your tree. This means that any occurrence of a is to be changed to an occurrence to b, using the function given as a transformation function.

To do this, you'll need to figure out what to do with each possible constructor of the Stree. Now, Null is easy -- it won't depend on a in the first place. Trickier is what to do with Fork. In Fork, there is one a, and two further Strees sitting around, so you need functions that take a -> b and that take Stree a -> Stree b. For the former, the invocation of mapStree gives you a function, and for the latter, mapStree f has the call signature you need (by partial application!).

For foldStree, you have some accumulation type b and your labeltype a, and an accumulation function that takes two values of type b and a value of type a and produces a b. This is helpful, not in the least because that accumulation function mirrors what you might have at any given Fork in the tree: by recursion you can assume you have results from both left and right Stree, and it only remains to combine those with the a value you have in the middle to give a new b value to hand up the recursion. The b parameter to foldStree provides you with enough of a standard value to get the whole thing started by getting a value for each leaf.

Thus, your foldStree will also need to be defined on the possible constructors: picking out the parameter for a Null value, and then for a Fork value, it needs to recurse into both Stree values before combining everything with the parameter combining function.

Please clarify in comments whether this helps you enough to deal with the problem: I (and many others here) can clarify, but the hope is for you to learn how to do it rather than to just hand you code.

不疑不惑不回忆 2024-10-06 00:12:33

我强烈推荐本课程中的讲座 5。

I highly recommend Lecture 5 from this course.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文