Reputation: 23
I have the following function in 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);
}
Now I want to make this function tail recursive. My idea is the following:
// 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);
}
Could someone please give me an advice how I can make this function tail recursive?
Upvotes: 1
Views: 258
Reputation: 51703
I wonder why the one who posted the answer with the helper method which was similar to my version deleted his post. I just wanted to analyse that and see what my mistakes are ...
I guess you meant
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)
}
Since T
and e
in is_in_tailrec
are always the same as T
and e
in is_in
, this can be rewritten as
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)
}
Upvotes: 0
Reputation: 27421
Your function is already tail recursive. If you mark it as @annotation.tailrec
it compiles just fine.
Upvotes: 2
Reputation: 3032
my suggestion is
{
case Nil => acc
case _ if acc => acc
case x :: xs => is_in_tailrec(e, xs, x == e)
}
or may be even
{
case x :: xs if !acc => is_in_tailrec(e, xs, x == e)
case _ => acc
}
Upvotes: 0
Reputation: 1572
Actually you don't need the helper method with accumulator here. Just check if e == x
returns false
, then call the method with the rest of the list, otherwise return 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)
}
Upvotes: 5