【发布时间】:2019-08-25 02:27:37
【问题描述】:
一直在寻找一种无需队列的方法,并使其尾递归。我认为 LazyLists 也可能有所帮助。队列会更快吗?我基本上是通过每个函数调用与下一级子级发送突变状态。
case class Tree [A] (
value : A,
Right: Option[Tree[A]],
Left: Option[Tree[A]]
)
object Tree {
def liftChildren[A](t: Tree[A]) = {
List(t.Left, t.Right).flatten
}
def findChild[A](value: A, t: Tree[A]) : Option[Tree[A]] = {
var lvl = 0
def searchChildren(t: List[Tree[A]]): (Option[Tree[A]], List[Tree[A]]) = {
// could be removed, just for fun
lvl += 1
t.foreach(tt => println(s"Scanning Level ${lvl.toString} Value ${tt.value.toString}"))
//
val curfind = t.find(tt => {
tt.value == value
})
curfind match {
case Some(tr) => (Some(tr), t)
case None => {
val children: List[Tree[A]] = t.flatMap(tt => Tree.liftChildren(tt))
children.isEmpty match {
case true => (None, List.empty)
case false => searchChildren(children)
}
}
}
}
searchChildren(List(t))._1
}
}
object main extends App {
println("hello world")
val tree = Tree[Int](
1,
Some(
Tree[Int](2, None, Some(
Tree[Int](5,None, Some(Tree[Int](6, None,None))))
)
) ,
Some(
Tree[Int](
3,
Some(
Tree[Int](4, None, Some(Tree[Int](7, None,None)))
), None
)
)
)
val res = Tree.findChild(6, tree)
println("FoundIt" + res)
}
它按我的预期工作。我只是想知道这是否会是更好或更惯用的 FP。猫图书馆会有所帮助吗?
【问题讨论】:
-
对我来说看起来不错。除了用于记录的 var lvl 之外,其他一切都是不可变的。据我所知,这是很好的功能代码。
-
我在liftChildren中使用lift这个词是否正确?这通常被称为电梯吗?
-
不,我不认为这就是 fp 人通常所说的提升。提升通常是指将一个类型移动到一些新的上下文中,通常是某种单子。但是“liftChildren”是不言自明的。当您在这里使用电梯时,人们会明白您的意思。
-
我认为让您的电梯功能足够灵活以适应树以外的类型是不值得的。它会降低您从未使用过的功能的可读性。我认为实现您想要的方法是使用更高种类的类型。您可能想为它创建另一个问题。 Luis 已经很好地回答了您现有的问题。
-
实际上,为了使您的 lift 函数可泛化到不同的类型,您需要提供一个参数,该参数是一个告诉 lift 如何将子项插入到 List 上下文中的函数。对我来说似乎没有必要。只是我的 2 美分。
标签: scala functional-programming breadth-first-search