【问题标题】:find the node with minimal value in binary tree with foldr用 foldr 在二叉树中找到具有最小值的节点
【发布时间】:2021-11-06 00:43:29
【问题描述】:

有人可以帮我定义一个函数 minTree,它使用 foldr 在二叉树中找到具有最小值的节点。 我开始了一些事情,但我不知道如何在我的代码中使用 foldr:

data Tree a 
    = Leaf
    | Node (Tree a) a (Tree a)
    deriving (Show, Eq)

  minTree :: (Ord a) => Tree a -> Maybe a
  minTree Leaf = Nothing
  minTree (Node Leaf a _) = Just a
  minTree (Node left a _) = minTree left
  minTree = foldr...

我被困在如何定义 foldr 以返回最小节点

【问题讨论】:

  • 现在看起来好多了,还是我需要修改这些行?
  • foldr 的类型签名是:Foldable t => (a -> b -> b) -> b -> t a -> b 所以你首先需要让 GHC 编译器相信你的树结构是 Foldable 类的一个实例。你用 -XDeriveFoldable 扩展试试运气了吗?

标签: haskell


【解决方案1】:

一个可能的解决方案如下:

data Tree a 
    = Leaf
    | Node (Tree a) a (Tree a)
    deriving (Show, Eq)

instance Foldable Tree where
  foldr f ini Leaf = ini
  foldr f ini (Node left x right) = f x $ foldr f (foldr f ini right) left

minTree :: (Ord a) => Tree a -> Maybe a
minTree tree = foldr minMaybe Nothing tree

minMaybe :: (Ord a) => a -> Maybe a -> Maybe a
minMaybe x Nothing = Just x
minMaybe x (Just y) = Just (min x y)

TreeFoldable 实例实现是后序遍历(右-左-根),这是代码的主要部分。 minMaybe 可能可以避免使用内置函数,但我保持它的表现力,所以主要部分保持清晰。

正如@ammalloy 所指出的,我们可以摆脱minMaybe 并使用coercefoldMapMin Semigroup。老实说,我不知道coerce 是如何工作的,但是foldMap 将一个函数应用于包装在具有Foldable 实例的数据类型中的数据,并使用他们的Monoidal 操作<> 聚合结果,这就是为什么此处使用Min

data Tree a 
    = Leaf
    | Node (Tree a) a (Tree a)
    deriving (Show, Eq)

instance Foldable Tree where
  foldr f ini Leaf = ini
  foldr f ini (Node left x right) = f x $ foldr f (foldr f ini right) left

minTree :: (Ord a) => Tree a -> Maybe a
minTree = coerce . foldMap (Just . Min)

【讨论】:

  • minTree = coerce . foldMap (Just . Min)
  • 谢谢@amalloy 我已将其添加到答案中。这有点超出我的认知。如果您认为合适,请检查并更正。谢谢。
  • @amalloy 让我感到困扰的是,使用它需要将每个元素包装在 Just 中,这是有代价的,尽管可以确定最终答案是 Just 还是 @ 987654339@ 检查根元素后立即返回。
  • 是的,这并不理想。如果 Prelude 的 minimum 是安全的,我们就可以使用它。事实上,我想不出任何便宜的单线。如果我们愿意使用两行代码,我们只需检查 Leaf,否则调用 minimum
  • 你不需要coerce。只需getMin 或其他任何名称。
猜你喜欢
  • 1970-01-01
  • 2014-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-05
相关资源
最近更新 更多