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