scala - Using an implicit parameter in a recursive function -


consider following hypothetical binary tree traversal code:

def visitall(node: node, visited: set[node]): unit = {   val newvisited = visited + node   if (visited contains node) throw new runtimeexception("cyclic tree definition")   else if (node.hasleft) visitall(node.left, newvisited)   else if (node.hasright) visitall(node.right, newvisited)   else () } 

i reduce duplication making visited parameter implicit, so:

def visitall(node: node)(implicit visited: set[node]): unit = {   implicit val newvisited = visited + node   if (visited contains node) throw new runtimeexception("cyclic tree definition")   else if (node.hasleft) visitall(node.left) // newvisited passed implicitly   else if (node.hasright) visitall(node.right) // newvisited passed implicitly   else () } 

however, gives following compile error:

ambiguous implicit values: both value visited of type set[node] , value newvisited of type scala.collection.immutable.set[node] match expected type set[node]

is there way can tell compiler "expect" implicit value visited parameter, not use implicit value when recursively invoking method?

unfortunatelly there no annotation-based solution, (@nopropagate implicit visited: set[node]), have shadow it:

scala> def visitall(node: node)(implicit visited: set[node]): unit = {      |     implicit val visited = set[node]()      |     visitall(node)      | } visitall: (node: node)(implicit visited: set[node])unit 

however, doesn't work if want access shadowed value:

scala> def visitall(node: node)(implicit visited: set[node]): unit = {      |     val unshadowed: set[node] = visited      |     implicit val visited: set[node] = unshadowed      |     visitall(node)      | } <console>:10: error: forward reference extends on definition of value unshadow ed            val unshadowed: set[node] = visited                                        ^ 

so, may (checked repl) then:

def visitall(node: node)(implicit visited: set[node]): unit = {        val newvisited = visited + node   ;{      implicit val visited = newvisited      if (visited contains node) throw new runtimeexception("cyclic tree definition")      else if (node.hasleft) visitall(node.left) // newvisited passed implicitly      else if (node.hasright) visitall(node.right) // newvisited passed implicitly      else ()   }     } 

or this:

def visitall(node: node)(implicit visited: set[node]): unit = {          ({implicit visited: set[node] =>         if (visited contains node) throw new runtimeexception("cyclic tree definition")        else if (node.hasleft) visitall(node.left) // newvisited passed implicitly        else if (node.hasright) visitall(node.right) // newvisited passed implicitly        else ()     })(visited + node)     } 

the idea move shadowed implicit inside nested block of code


Comments

Popular posts from this blog

asp.net mvc - SSO between MVCForum and Umbraco7 -

Python Tkinter keyboard using bind -

ubuntu - Selenium Node Not Connecting to Hub, Not Opening Port -