scala - tail recursion fails (possibly because of implicit cons conversion) -
i have believe simple tail-recursive function. however, @tailrec
tells me otherwise.
@tailrec def _next(continue : string, current : list[long], first : boolean ) : stream[long] = { current match { case head :: tail => head #:: _next(continue, tail, false) //this line breaks tailrec case nil if first => empty case _ => { val (nc, nl) = getids(continue) _next(nc, nl, true) } } }
which presents me with
[error] not optimize @tailrec annotated method _next: contains recursive call not in tail position [error] case head :: tail => head #:: _next(continue, tail, false) [error] ^
it has implicit notification receive eclipse: - implicit conversions found: _next(continue, tail, false) => conswrapper(_next(continue, tail, false))
, unfortunately, isn't helping me resolve issue.
how can fix this, and, brownie points, did go wrong thinking tail-recurse?
the problem last operation in code not call _next
, stream
cons operation #::
.
one solution use streambuilder
build stream , keep streambuilder
accumulator variable.
@tailrec def _next(continue : string, current : list[long], first : boolean, acc: stream.streambuilder[long]) : stream[long] = { current match { case head :: tail => acc += head _next(continue, tail, false, acc) case nil if first => acc.result case _ => { val (nc, nl) = getids(continue) _next(nc, nl, true, acc) } } }
this not particularly efficient - streambuilder
more appropriate if add entire collections using ++=
instead of +=
. reason, consider changing code this:
@tailrec def _next(continue : string, current : list[long], first : boolean, acc: stream.streambuilder[long]) : stream[long] = { current match { case nil => acc.result case list => acc += list val (nc, nl) = getids(continue) _next(nc, nl, true, acc) } }
Comments
Post a Comment