【问题标题】:Haskell - Translate a list to a recursive data structureHaskell - 将列表转换为递归数据结构
【发布时间】:2020-03-25 05:48:04
【问题描述】:

我在 Haskell 教科书中发现了这个问题。给定一个递归数据结构:

data Foo = A Foo Foo | B Int Foo | C Int

创建一个函数:

createFooFromList :: [Int] -> Foo -> Foo

接收一个列表和一个Foo,将列表应用于Foo,并返回新的Foo

“应用”的含义最好用一个例子来描述。

假设我们有一个定义为B 0 (B 1 (A (B 0 (C 1)) (B 1 (C 1))))Foo,我们必须将列表[0,0,1,0,2,0] 应用到这个Foo。为此,只需获取给定序列中的每个整数,然后将Foo 结构中的整数按顺序替换为序列中的这些整数。

所以对于上面的例子,我们的输出是B 0 (B 0 (A (B 1 (C 0)) (B 2 (C 0))))

到目前为止,我已经创建了一个将列表应用于BC 结构的函数。 C 是微不足道的,B 也很简单,因为我只需将列表的头部设置为 BInt 参数,然后将列表的其余部分递归地应用到 Foo 的 @987654339 部分@。但是我不确定如何处理A

【问题讨论】:

  • 输出中的 2 在哪里?
  • 您能分享一下您已经完成的工作以及您遇到的问题吗?我会假设某种 CPS 方法,但这可以通过多种方式完成。
  • 什么命令?广度优先、深度优先还是其他?
  • 如果无法“应用”列表怎么办?
  • @MartinKristiansen 正如我在问题中所说,我正在为 A 苦苦挣扎。现在我的想法是我会有某种辅助函数来“扫描”某个路径以查找多少整数都在其中,这样我的算法就可以知道要向 A 中的任一 Foo 提供多少列表。

标签: haskell recursion tree binary-tree


【解决方案1】:

这里有一个提示:

我将首先编写一个辅助函数,它接受[Int]Foo 参数,并且不仅返回输出Foo,还返回一个额外的[Int],表示输入列表中尚未出现的数字用过,还。 因此,生成的输出类型可以是一对。

这里的直觉是这个辅助函数并不假设输入[Int]列表包含正确数量的Foo输入,而是允许更多Ints存在,并返回那些在多余的。

使用这个辅助函数,你可以处理里面有两个Foos的A的情况:你在第一个Foo上调用辅助函数,得到多余的Ints,然后你将它们用于第二个Foo,并返回新的多余Ints。

(更高级的方法是使用State [Int] monad,但上述基本方法应该没问题。)

【讨论】:

  • 有趣的是,高级方法和基本方法是一样的
猜你喜欢
  • 2020-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-24
  • 1970-01-01
  • 1970-01-01
  • 2022-10-04
相关资源
最近更新 更多