haskell - Haskell - 将列表转换为递归数据结构
问题描述
我在 Haskell 教科书中发现了这个问题。给定一个递归数据结构:
data Foo = A Foo Foo | B Int Foo | C Int
创建一个函数:
createFooFromList :: [Int] -> Foo -> Foo
它接受一个列表和一个Foo
,将列表应用于Foo
,并返回新的Foo
.
最好用一个例子来描述“应用”的含义。
假设我们有一个Foo
定义为的B 0 (B 1 (A (B 0 (C 1)) (B 1 (C 1))))
,我们必须将列表应用[0,0,1,0,2,0]
到这个Foo
。为此,只需取给定序列中的每个整数,然后用序列中的Foo
这些整数按顺序替换结构中的整数。
所以对于上面的例子,我们的输出是B 0 (B 0 (A (B 1 (C 0)) (B 2 (C 0))))
到目前为止,我已经创建了一个将列表应用于B
andC
结构的函数。C
是微不足道的,B
也很容易,因为我只需将列表的头部设置为 的Int
参数B
,然后递归地将列表的其余部分应用于 的Foo
部分B
。但是我不确定如何处理A
。
解决方案
这里有一个提示:
我将首先编写一个辅助函数,该函数接受[Int]
andFoo
参数,不仅返回输出,还返回Foo
一个[Int]
表示输入列表中尚未使用的数字的附加函数。因此,生成的输出类型可以是一对。
这里的直觉是,这个辅助函数不假设输入[Int]
列表包含正确数量的Foo
输入,而是允许Int
存在更多的 s,并返回超出的那些。
使用这个辅助函数,你可以处理里面A
有两个Foo
s的情况:你在第一个上调用辅助函数Foo
,得到多余Int
的s,然后将它们用于第二个Foo
,并返回新的多余Int
s。
(更高级的方法是使用State [Int]
monad,但上述基本方法应该没问题。)
推荐阅读
- css - 使用 ::after 选择器的按钮悬停效果不可见
- c# - 是否可以使用 LINQ 指定内联数组?
- javascript - Webpack 同时使用 css 模块并导入整个 css 文件
- wordpress - 默认媒体上传器未显示在 wordpress 网站中
- javascript - 使用ajax和laravel访问路由时如何修复404未找到
- javascript - 使用 Google App 脚本将数据从一张表复制到另一张表时执行缓慢
- java - 如何使用 Java Stream 运算符获取子值的子值并作为地图收集
- android - Firebase ML Kit Android - API 密钥无效
- apache-kafka - Zookeeper 在 Kafka 最新版本中是否已弃用?
- flutter - 根据风味支持不同的资产集