【问题标题】:zipWith for trees in HaskellzipWith 用于 Haskell 中的树
【发布时间】:2016-04-04 19:04:09
【问题描述】:

我正在使用 Haskell 表达学院学习 Haskell:通过多媒体学习函数式编程,我不确定如何解决这个练习。

使用由

给出的树的定义
data Tree a = Node (Tree a) (Tree a) | Leaf a

定义列表函数zipzipWith 的树版本。那里 将是树叶或树木形状不同的地方 您必须在其中做出设计决策。尝试做出你的决定 尽可能优雅。

对于zip,我有这个,但我不确定它是否“优雅”

zipTree :: Tree a -> Tree b -> Tree (a,b)
zipTree (Leaf a)     (Leaf b)     = Leaf (a,b)
zipTree (Node l1 r1) (Node l2 r2) = 
  let l = zipTree l1 l2
      r = zipTree r1 r2 
  in Node l r 

-- Problems...
zipTree (Node _ _)  (Leaf _)   = Node undefined undefined
zipTree (Leaf _)    (Node _ _) = Node undefined undefined

虽然我知道 zipWith 的优雅定义,但我不确定如何使其具有 zipWith 功能。

zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith f (x:xs) (y:ys) = f x y : zipWith f xs ys
zipWith _ _ _ = []

【问题讨论】:

  • 请注意,您只需要定义zipTreeWith :: (a -> b -> c) -> (Tree a) -> (Tree b) -> (Tree c),因为zipTree 就是zipWith = zipTreeWith (,) 的特例。

标签: haskell binary-tree


【解决方案1】:

首先,我认为您的解决方案并不优雅,因为您使用的是undefined。 您希望尽可能避免部分函数和结构,并且简单地在树结构中插入一些 Node undefined undefined 听起来不是一个好主意。

想一想:一旦你有了Node undefined undefined,它将如何与树上的其他操作一起作用?您可能会遇到大量异常。

所以你必须找到一个替代方案。

zipTree (Node l r) (Leaf a) = Node x y
    where
        x = ... ? 
        y = ... ? 

现在应该如何定义xyx 应该依赖于lLeaf a,而y 应该依赖于rLeaf a

定义这种情况的最简单方法是简单地执行递归调用:

zipTree (Node l r) a@(Leaf _) = Node (zipTree l a) (zipTree r a)

所以我们将lr 子树中的所有叶子与叶子a 一起压缩。

至于zipWithTree:这很简单。执行压缩时必须添加f 参数并使用f x y 而不是(x, y),这仅在Leaf v Leaf 情况下完成:

zipWithTree f (Leaf a) (Leaf b) = Leaf $ f a b

显然您必须将f 参数添加到所有规则并将f 传递给递归调用。


注意,还有另一种定义zipWith的方式,即:

zipTree (Node _ _) (Leaf a) = Leaf (undefined, a)

这仍然不是一个好的解决方案,因为它引入了undefined,但是它与Node undefined undefined 解决方案相比具有一些优势:

  1. 它的作用类似于列表中的zipzip [1,2] [1,2,3,4] == [(1,1), (2,2)] 所以你在较短的列表结束时停下来。

  2. undefined这个值。例如,这允许:

    mapTree snd (zipTree x y) == y
    

    只要x 有更长的分支。使用Node undefined undefined 你有mapTree f (zipTree x y)总是一个例外,只要树不是同构的(因为mapTree 将尝试评估undefined)。

【讨论】:

    猜你喜欢
    • 2015-07-06
    • 1970-01-01
    • 2014-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-08
    • 1970-01-01
    相关资源
    最近更新 更多