Haskell - 如何基于二叉树的foldr创建mapTree函数?

2024-03-14

这是《Haskell 编程的第一原理》第 11 章代数数据类型中的一个问题:

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

我们实际上并没有将值插入到现有的树中;而是将值插入到现有的树中。每次我们想要向数据结构中插入一个值时,我们都会构建一棵全新的树:

insert' :: Ord a => a -> BinaryTree a -> BinaryTree a
insert' b Leaf = Node Leaf b Leaf
insert' b (Node left a right)
  | b == a = Node left a right
  | b < a = Node (insert' b left) a right
  | b > a = Node left a (insert' b right)

这是BinaryTree数据结构的映射函数:

mapTree :: (a -> b) -> BinaryTree a -> BinaryTree b
mapTree _ Leaf = Leaf
mapTree f (Node left a right) = 
  Node (mapTree f left) (f a) (mapTree f right)

为二叉树编写foldr

给定我们提供的二叉树的定义,为二叉树编写一个变形。

-- any traversal order is fine
foldTree :: (a -> b -> b) 
  -> b 
  -> BinaryTree a 
  -> b

上面的类型是对那些在应用折叠函数之前不将树转换为列表的人的提示。

重写二叉树的映射

使用刚刚编写的foldTree,使用foldTree重写mapTree。 缺少 Ord 约束是故意的,您不需要使用插入函数。

mapTree' :: (a -> b)
  -> BinaryTree a
  -> BinaryTree b
mapTree' f bt =
  foldTree undefined undefined undefined

在以下方面的大量帮助下,我设法得到了适用于第一个问题的答案:https://github.com/johnchandlerburnham/hpfp/blob/master/11/BinaryTree.hs https://github.com/johnchandlerburnham/hpfp/blob/master/11/BinaryTree.hs

我的答案:

foldTree f b Leaf = b
foldTree f b (Node left a right) 
  = (foldTree f tempb left) where
    tempb = (f a) tempright
    tempright = foldTree f b right

然而,对于关于为 BinaryTree 编写新的 mapTree 的第二个问题,我找不到答案。上面提供了原始的mapTree。甚至连答案都在约翰钱德勒伯纳姆链接 https://github.com/johnchandlerburnham/hpfp/blob/master/11/BinaryTree.hs使用不同的折叠树。

有人可以根据我对第一个问题的回答帮助获得第二个问题的可行答案吗?或者第一个问题需要另一个答案吗?

用于测试的树可以是:

testTree :: BinaryTree Integer
testTree =
  Node (Node Leaf 3 Leaf) 1 (Node Leaf 4 Leaf)

你不能写mapTree用一个foldTree与那个签名。 (正如 @chi 指出的,技术问题是foldTree有错误的签名是真正的变形BinaryTree.) 事实上,如果您加载链接的 Haskell 文件BinaryTree.hs https://raw.githubusercontent.com/johnchandlerburnham/hpfp/master/11/BinaryTree.hs,你会看到mapTree'无法正常工作:

λ> :l BinaryTree
λ> mapTree (+1) testTree
Node (Node Leaf 2 Leaf) 3 (Node Leaf 4 Leaf)
λ> mapTree' (+1) testTree
Node (Node (Node Leaf 3 Leaf) 2 Leaf) 4 Leaf

它给出了正确的节点值,但树的结构是错误的。

我没有那本书的副本,所以我无法确切地看到你所看到的内容,但也许这些笔记 https://gist.github.com/DadgadCafe/7b544493bb440be3b440ecdbc3581660会有帮助的。在11.15节的最后,作者讨论了2参数和3参数版本foldTree,并且表明只有mapTree'使用 3 参数版本编写的代码将正常工作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Haskell - 如何基于二叉树的foldr创建mapTree函数? 的相关文章

  • 为什么 GeneralizedNewtypeDeriving 没有安全的 Haskell?

    来自 GHC 手册 第安全语言 http www haskell org ghc docs 7 6 2 html users guide safe haskell html safe language 模块边界控制 使用安全语言编译的 Ha
  • 应用交换律

    带有效果的应用程序编程 http staff city ac uk ross papers Applicative html麦克布莱德和帕特森的论文提出了互换法 u lt gt pure x pure f gt f x lt gt u 为了
  • 无法通过 cabal 安装“System.Random”

    我尝试通过 Cabal 通过 Powershell 和 Git Bash 安装 System Random 得到这个结果 PS C Users xxx gt cabal install random Resolving dependenci
  • 计算/获取分层数据的“级别”

    好吧 我真的不知道这是否是正确的标题 但我不知道如何称呼它 我的问题是关于我的作业 我现在已经工作了几个小时 主题是 函数式数据结构 我有点陷入困境 我不知道如何继续 所以我需要编写一个具有以下签名的函数 data Heap e t Hea
  • 副作用是纯函数中找不到的一切吗?

    可以肯定地说 以下二分法成立 每个给定的函数是 要么纯粹 或有副作用 如果是这样 函数的 副作用就是纯函数中找不到的任何东西 这很大程度上取决于您选择的定义 可以公平地说 函数是pure or impure 纯函数始终返回相同的结果并且不会
  • 算法 - 如何有效删除列表中的重复元素?

    有一个list L 它包含以下元素任意类型each 如何有效删除此类列表中的所有重复元素 必须保留订单 只需要一个算法 因此不允许导入任何外部库 相关问题 在Python中 从列表中删除重复项以使所有元素都是唯一的最快算法是什么在维持秩序的
  • 表达式“ap zip tail”如何工作

    我想知道怎么写f x zip x tail x 点免费 所以我使用了pointfree程序 结果是f ap zip tail ap作为 Control Monad 的函数 我不明白点自由定义是如何工作的 如果我能从类型的角度去理解的话 希望
  • 可以通过Data.Function.fix来表达变形吗?

    我有这个可爱的fixana这里的函数执行速度比她的姐妹快 5 倍左右ana 我有一个criterion报告支持我这一点 ana alg Fix fmap ana alg alg fixana alg fix f gt Fix fmap f
  • GHC 是否使用存在类型的动态调度?

    下面的代码是否使用了 C 或 Java 中所理解的动态调度 据我了解 在最后一行 编译器不可能在编译时知道要调用哪个 实现 但代码会编译并产生正确的结果 有人可以解释一下 这背后有什么样的实现 例如 vptr 吗 LANGUAGE Exis
  • 我应该使用镜头中的什么来按索引构建只读吸气剂?

    我有一个内部细节被隐藏的类型 我想提供某种镜头 可以在特定索引处读取所述类型的元素 但是not修改它们 一个Ixed我的类型的实例似乎没有做我想要的事情 因为它明确允许修改 尽管不允许插入或删除 如果我想允许只读索引 我不确定我使用什么 如
  • 在 haskell 中处理 IO 与纯代码

    我正在编写一个shell脚本 我在haskell中的第一个非示例 它应该列出一个目录 获取每个文件大小 进行一些字符串操作 纯代码 然后重命名一些文件 我不确定我做错了什么 所以有两个问题 我应该如何安排这样的程序中的代码 我有一个具体问题
  • 存在函数依赖关系时类型推断如何工作

    考虑下面的代码 LANGUAGE MultiParamTypeClasses FlexibleInstances FunctionalDependencies UndecidableInstances FlexibleContexts cl
  • 从字符串列表创建 TfRecords 并在解码后在张量流中提供图形

    目的是创建 TfRecords 数据库 给定 我有 23 个文件夹 每个文件夹包含 7500 个图像 以及 23 个文本文件 每个文件有 7500 行描述单独文件夹中 7500 个图像的特征 我通过以下代码创建了数据库 import ten
  • 我应该使用什么递归方案来重复有效的操作,直到其结果符合某些标准?

    也就是说 我要问的是一个循环 effectful Int gt IO Int effectful n do putStrLn Effect show n return n condition 3 final Int gt IO final
  • 有没有办法在 Emacs 中使用 Djinn 自动生成 Haskell 代码?

    标题几乎说明了一切 我正在寻找这样的东西 f Int gt Bool gt Int f body Djinn 可以使用定理证明来通过证明该类型存在来生成此类函数的代码 我想知道 是否有现有的方法可以从 Emacs 中获取此功能 因此 我不需
  • 管道中缺少 ResourceT 实例

    我在尝试使用时遇到奇怪的错误ResourceT http hackage haskell org package conduit 1 0 9 1 docs Data Conduit html t 3aResourceT来自管道 1 0 9
  • 简单的秒差距示例会产生类型错误

    我正在尝试编译这个简单的秒差距代码 import Text Parsec simple letter 但我不断收到此错误 No instance for Stream s0 m0 Char arising from a use of let
  • XSLT 将平面树结构转换为列表

    我有一个描述eshop树结构的xml文件 我只需要获取所有子组的列表 我不知道结构中有多少个父 子级别 输入 xml 如下所示
  • 为什么以下内容会并行运行而不是顺序运行?

    给定以下函数evalPair parPair and deepSeq分别 evalPair Strategy a gt Strategy b gt Strategy a b evalPair sa sb a b do a lt sa a b
  • C 编程 - 文件 - fwrite

    我有一个关于编程和文件的问题 while current NULL if current gt Id Doctor 0 current current gt next id doc current gt Id Doctor if curre

随机推荐

  • Ruby Mechanize:点击链接

    在 Mechanize on Ruby 中 我必须为我访问的每个新页面分配一个新变量 例如 page2 page1 link with text gt Continue click page3 page2 link with text gt
  • Cucumber 在一段时间后逐步停止执行

    我的一个测试会等到事件发生Then步 如果测试工作正常 则没有问题 但如果测试失败 即没有触发任何事件 那么它就会挂起 我怎样才能设置超时Cucumber I know JUnit有一个超时参数 您可以在 Test annotation h
  • 使用 Spark SQL 跳过/获取

    如何使用 Spark SQL 实现跳过 获取查询 典型的服务器端网格分页 我在网上搜索过 只能找到非常基本的示例 例如 https databricks training s3 amazonaws com data exploration
  • 使用键盘快捷键聚焦于文本字段

    我有一个 macOS Monterrey 应用程序 其中包含TextField在工具栏上 我用它来搜索我的应用程序上的文本 现在 我正在尝试添加键盘快捷键以专注于TextField 我尝试了下面的代码 添加带有快捷方式的按钮作为测试这是否可
  • 在sqlite不同数据库中触发

    我有 2 个不同的数据库 A 和 B 我需要创建一个触发器 当我在数据库 A 的表 T1 中插入任何条目时 数据库 B 的表 T2 的条目将得到已删除 请给我推荐一个方法 这不可能 在SQLite中 触发器内部的DML只能修改同一数据库的表
  • 将字符串提取函数包装在 ifelse 语句中

    下面的问题是一个延伸这个问题 https stackoverflow com questions 74135095 adding a column to the data that looks for a list of words and
  • 在现实世界应用中使用语义网络技术的示例[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 您正在开发使用 RDF OWL SPARQL 技术的 可能是商业的 产品吗 如果是这样 您能描述一下您的产品吗 O Reilly 的
  • 写入/编辑 CSV 文件(不要重写整个文件!)

    我需要替换直接在 CSV 文件上操作的客户端的某些功能 该文件用作系统的配置文件 搜索到的大多数案例都是关于从 CSV 读取到其他格式的 其他将整个 CSV 放入内存 附加专用行和更改 然后将它们写回新文件 或覆盖现有文件 我想更聪明地完成
  • Jetpack Compose 应用程序范围内的条件 TopAppBar 最佳实践

    我有一个 Android Jetpack Compose 应用程序 它使用BottomNavigation and TopAppBar可组合项 从通过打开的选项卡BottomNavigation用户可以更深入地导航到导航图 问题 The T
  • 如何在python中实现小批量梯度下降?

    我刚刚开始学习深度学习 当谈到梯度下降时 我发现自己陷入了困境 我知道如何实现批量梯度下降 我知道它是如何工作的以及小批量和随机梯度下降在理论上是如何工作的 但实在无法理解如何用代码实现 import numpy as np X np ar
  • 无法再加载 rgdal

    我在 Ubuntu 上将 GDAL 更新为 2 2 2 现在rgdal在 R 中失败 当我尝试加载时收到此消息rgdal 我也尝试更新rgdal 但没有成功 Error in get method envir home lazy load
  • 在 Android 应用程序中从 Web 获取 UTC 日期

    我想要一个UTC date对于我的 Android 应用程序来说 它是独立于设备 和用户 的 我听说过一些事情 比如从 NTP 服务器获取日期 但无法从 google 或 SO 找到任何帮助 那么任何人都可以帮我提供一些代码片段或链接吗 提
  • 正确处理文件流和二进制流以及处理文件流

    事实上 我尝试对我的代码进行防错 但最终使它看起来相当混乱 我设置了一个函数来读取某种类型的文件 我希望函数在出现问题时返回 false 如果一切正常则返回 true 我无法弄清楚如何构建一切 我有一个尝试打开文件流的初始 try catc
  • 在 ServiceProvider 中使用 Entity Framework Core 3.1 和 UseInMemoryDatabase 选项(作用域生命周期)

    我已将一个 Web 应用程序项目从 NET Core 2 1 迁移到 3 1 也将 EF Core 从 2 1 1 迁移到 3 1 0 迁移后 一些单元测试不再工作 抛出重复键数据库异常 我模拟了这个问题并意识到 EF core 带有选项U
  • 带有远程文件的 HTML5 文件 API

    我尝试了几个小时使用 HTML5 文件系统添加带有 URL 的远程文件 例如http example com doc pdf http example com doc pdf 而不是通过文件输入获得的文件 因为我希望该过程是自动的 我有多个
  • 在 eclipselink 中设置隔离级别

    我想使用 eclipse 链接设置隔离级别 我尝试了这两种方法来做到这一点 java sql Connection mgr EMF get createEntityManager tx mgr getTransaction tx begin
  • Android Studio 与 Transfuse

    我可以在我的 android 项目中成功设置 Transfuse 但是当使用 Android Studio 运行该应用程序时 它失败了 可能是因为 Manifest xml 必须为空才能让 Transfuse 处理 有人曾经把这些一起工作过
  • 通过ViewBag传递模型对象

    我想知道是否可以通过 ViewBag 传递模型对象 我尝试了以下代码 但不知何故在我的视图中 它仅显示模型的路径 控制器 public ActionResult Tempo DateTime date1 new DateTime 1990
  • 安装签名的 msi 安装程序时出现奇怪的“程序名称”[重复]

    这个问题在这里已经有答案了 登录 MSI 安装程序后 我遇到以下问题 我正在使用signtool exe并且msi文件签名正常 但是当我测试它时 显示我公司名称的UAC确认对话框显示55847 msi的 程序名称 而不是我的安装文件的名称
  • Haskell - 如何基于二叉树的foldr创建mapTree函数?

    这是 Haskell 编程的第一原理 第 11 章代数数据类型中的一个问题 data BinaryTree a Leaf Node BinaryTree a a BinaryTree a deriving Eq Ord Show 我们实际上