【问题标题】:How do I define map and fold on search trees?如何在搜索树上定义地图和折叠?
【发布时间】:2010-10-20 22:57:54
【问题描述】:

我有一个定义为的搜索树:

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 :: (Ord a) => (b -> a -> b -> b) -> b -> Stree a -> b

我不完全了解发生了什么,也不知道该怎么做。

【问题讨论】:

  • (离题)。 GHC可以自动派生Functor和Foldable来定义以上两个函数(前提是Ord a =>约束不存在)。
  • 不清楚Ord的作用是什么。我假设这棵树是由 Ord 实例从左到右排序的。在这种情况下,是否允许“mapStree”假设其功能是单调的(即保留顺序)或者 mapStree 是否需要在运行时重新排序?
  • 教授所说的大部分内容都不清楚,我什至不确定他是否知道Ord自己做了什么,因为他无法解释。

标签: search haskell tree higher-order-functions


【解决方案1】:

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

为此,您需要弄清楚如何处理Stree 的每个可能的构造函数。现在,Null 很容易——它首先不依赖于a。更棘手的是如何处理Fork。在Fork 中,有一个a,还有两个Strees,所以你需要有a -> bStree a -> Stree b 的函数。对于前者,mapStree 的调用为您提供了一个函数,对于后者,mapStree f 具有您需要的调用签名(通过部分应用程序!)。

对于foldStree,你有一些累加类型b和你的标签类型a,以及一个累加函数,它接受两个b类型的值和一个a类型的值,并产生一个b .这很有帮助,至少因为该累积函数反映了树中任何给定Fork 可能拥有的内容:通过递归,您可以假设您有来自左右Stree 的结果,它只剩下组合那些具有a 值的人在中间给出一个新的b 值来提交递归。 foldStreeb 参数为您提供了足够的标准值,通过获取每个叶子的值来开始整个过程​​。

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

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

【讨论】:

  • 您对mapStree f (Fork left x right) 的第二次尝试看起来不错:您需要将mapStree f 应用于leftright,并且您需要将f 应用于@987654355 @.
  • @a.d. f(x) 在您的尝试中没有做您认为的那样 - 它会将 f 和 y 作为连续参数传递给 Fork,这将导致类型错误。看起来你理解函数应用程序语法,因为你得到了 (mapStree f xt) 和 (mapStree f yt) 正确,所以我猜这可能只是一个错字。
【解决方案2】:

我强烈推荐this course的第5讲。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-29
    • 2012-01-19
    • 2019-03-12
    • 2018-07-30
    • 1970-01-01
    • 2011-01-07
    相关资源
    最近更新 更多