我在scala中具有以下功能:
def is_in[T](e: T, as: List[T]) : Boolean = as match
{
case Nil => false;
case x::xs => e == x || is_in(e, xs);
}
现在,我想使此函数尾部递归。我的想法如下:
// tail recursive:
def is_in[T](e: T, as:List[T]) : Boolean =
{
@tailrec
def is_in_tailrec[T](e: T, as:List[T], acc: Boolean) : Boolean =
{
as match
{
case Nil => acc;
case x::xs => is_in_tailrec(... here I got stuck ...);
}
}
is_in_tailrec(e, as, 1);
}
有人可以给我建议如何使该函数尾部递归吗?
答案 0 :(得分:5)
实际上,这里不需要带累加器的辅助方法。只需检查e == x
是否返回false
,然后使用列表的其余部分调用该方法,否则返回true:
def is_in[T](e: T, as: List[T]): Boolean = as match {
case Nil => false
case x :: _ if e == x => true
case _ :: xs => is_in(e, xs)
}
答案 1 :(得分:2)
您的函数已经是尾递归了。如果将其标记为require 'nokogiri'
doc = Nokogiri::HTML(<<EOT)
<a href="http:example.com">blah</a>
<a href="mailto:foo@bar.com">blah</a>
EOT
doc.at('a[href^="mailto:"]')
.to_html # => "<a href=\"mailto:foo@bar.com\">blah</a>"
,则可以正常编译。
答案 2 :(得分:0)
我的建议是
{
case Nil => acc
case _ if acc => acc
case x :: xs => is_in_tailrec(e, xs, x == e)
}
或者甚至是
{
case x :: xs if !acc => is_in_tailrec(e, xs, x == e)
case _ => acc
}
答案 3 :(得分:0)
我想知道为什么用与我的版本相似的helper方法发布答案的人删除了他的帖子。我只是想分析一下,看看我的错误是什么...
我想你是说
def is_in[T](e: T, as: List[T]) : Boolean = {
@tailrec
def is_in_tailrec[T](e: T, as: List[T], acc: Boolean): Boolean = as match {
case Nil => acc
case x :: xs => is_in_tailrec(e, xs, e == x || acc)
}
is_in_tailrec(e, as, false)
}
由于T
中的e
和is_in_tailrec
与T
中的e
和is_in
始终相同,因此可以将其重写为< / p>
def is_in[T](e: T, as: List[T]) : Boolean = {
@tailrec
def is_in_tailrec(as: List[T], acc: Boolean): Boolean = as match {
case Nil => acc;
case x :: xs => is_in_tailrec(xs, e == x || acc)
}
is_in_tailrec(as, false)
}