简体   繁体   中英

call-by-name function is evaluated before invoke

I have a logic look like this:

def process[T](f1: => T, f2: => T): T = {
  Try { /*Do Something*/ } match {
    case Failure(_) => Try { /*Do something*/ } match {
      case Failure(e) => throw e
      case Success(v1) => 
        // I just need this succeed value be passed to my f1
        // but I dont know how. So...
        implicit val v: V1 = v1
        f1 
    }
    case Success(v2) =>
      // I just need this succeed value be passed to my f1
      // but I dont know how. So...
      implicit val v: V2 = v2
      f2
}

then I define f1 and f2 and call this process function like this:

// just for describing this problem clearly
// V1, V2 are two successful output types from the above snippet's branches.
// They are two different types.
// Bar just a dummy Object, Unit will do the same
// I use Bar(v) just to show I processed v in this function.
def f1(implicit v: V1): Bar = Bar(v)
def f2(implicit v: V2): Bar = Bar(v)

process(f1, f2)

then I got error that says No implicit found for f1 . Any Help?

Implicits don't work the way you assumed they do. You would have to pass implicit function type instead of by-name param, but implicit function type is introduced in Dotty:

// if it was Dotty
def process[T](f1: (given V1) => Bar, f2: (given V2) => Bar) = ...

There are no similar constructs in Scala 2. Closest approximation is handwritten trait with apply that takes implicit arguments.

trait F1 { def apply()(implicit v: V1): Bar }
trait F2 { def apply()(implicit v: V2): Bar }

def process[T](f1: F1, f2: F2): T = {
  Try { /*Do Something*/ } match {
    case Failure(_) => Try { /*Do something*/ } match {
      case Failure(e) => throw e
      case Success(v1) =>
        implicit val v: V1 = v1
        f1()
    }
    case Success(v2) =>
      implicit val v: V2 = v2
      f2()
  }
def f1: F1 = new F1 { def apply()(implicit v: V1): Bar = Bar(v) }
def f2: F2 = new F2 { def apply()(implicit v: V2): Bar = Bar(v) }

process(f1, f2)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM