How does this triple work work?

I have used this implementation of the 3d scala operator quite recently, especially with toggling enabled / disabled images, however I usually understand what pieces of code I find confusing me. I also want to modify it a bit to better suit my needs. I like the operator-ish syntax over verbose if else blocks etc.

implicit def BooleanBool(b: Boolean): Bool = Bool(b)

case class Bool(b: Boolean) {
  def ?[X](t: => X) = new {
    def |(f: => X) = if (b) t else f
  }
}

      

So my understanding is that the implicit creates a Bool object, with? as a function. This function should return a value of type X. I'm trying to figure out the rest.

Here are my questions:

  • How does a nested function work? | function.
  • What order does the code actually allow?
  • How can I change it so that there is an option to have no else clause? eg. isTheSkyBlue ()? goOutside ()
  • Is there a downside to nesting ternary operators like:

    isTheSkyBlue() ? goOutside() | {
        isTheInternetOn() ? playVideoGame() | read() 
    }
    
          

  • Whether suppuration can be modified to act like a case statement. Those. use operator a => or similar. eg.

    isTheSkyBlue() ? goOutside() | =>
        isTheInternetOn() ? playVideoGame() | read() 
    
          

    Or even get rid of it all

    isTheSkyBlue() ? goOutside() |
        isTheInternetOn() ? playVideoGame() | read() 
    
          

+3


source to share


2 answers


To answer 1 and 2, the nested function is pretty simple, symbols ?

|

are just method names. I renamed ?

to question

and |

to or

and added to an explicit call Bool

. This is what de-sugared looks like:

  case class Bool(b: Boolean) {
    def question[X](t: => X) = new {
      def or(f: => X) = if (b) t else f
    }
  }

  Bool(isTheSkyBlue()).question(goOutside()).or(
    Bool(isTheInternetOn()).question(playVideoGame()).or(read())
  )

      

3 is a little more complex because it otherwise if

requires else

what would it return? If you are only doing a side effect, you can do something like this:



  implicit def OneWayBooleanBool(b: Boolean): OneWayBool = OneWayBool(b)

  case class OneWayBool(b: Boolean) {
    def ??[X](t: => X) = if (b) t
  }

  isTheSkyBlue() ?? goOutside()

      

For question 4, there is no real nesting issue other than complex code.

For question 5, you really can't do this because of how scala will resolve anything, unless someone else has an idea how to do it.

+3


source


Complementing @ Noah's answer:

The function ?

does not return a type value X

, it returns an anonymous class. We could have made it a regular class (ignoring laziness for now):



class PartiallyEvaluated[X](b: Boolean, t: X) {
  def |(f: X) = if(b) t else f
}
class Bool(b: Boolean) {
  def ?[X](t: X) = new PartiallyEvaluated(b, t)
}

      

Scala always resolves a b c d e

like a.b(c).d(e)

. If you want to add a "end chain" method, you can make the first expression return some lazy thing that knows what to do when called on another object. Or you could create a syntax for for

/ yield

to chain these things, but I suspect this will be more confusing than helpful.

+1


source







All Articles