Question

I tried the following to create an option-checking style in code:

object Test {
  trait Check
  object x extends Check
  def option() = false
  def option(xx: Check) = true
  implicit class AugmentCheck(s: String) {
    def apply() = ""
    def apply(xx: Check) = s
  }
}
import Test._

val delete = option ( x )
val force  = option (   )

val res = "mystring" (   )

But I face the following problem:

<console>:11: error: type mismatch;
 found   : String("mystring")
 required: ?{def apply: ?}
Note that implicit conversions are not applicable because they are ambiguous:
 both method augmentString in object Predef of type (x: String)scala.collection.
immutable.StringOps
 and method AugmentCheck in object Test of type (s: String)Test.AugmentCheck
 are possible conversion functions from String("mystring") to ?{def apply: ?}
           val res = "mystring" (   )
                     ^
<console>:11: error: String("mystring") does not take parameters
           val res = "mystring" (   )

This is unfortunate, because even if there is ambiguity in the symbol name, there shouldn't be any ambiguity in the function signature.

If I introduce the method "apply", it works fine when there is an argument, but not without:

           val res = "mystring" apply ( x )

           res == ""

How can I remove the keyword "apply" in this case?

Was it helpful?

Solution

Instead of representing the on and off states with x or  , what about using y for yes and n for no?

object Test {
  val y = true
  val n = false
  class DefaultConfigValue[U](val v: U)
  implicit class ConfigValue[U](v: U) {
    def y = v
    def n(implicit default: DefaultConfigValue[U]) = default.v
  }
  implicit val defaultConfigString = new DefaultConfigValue("")
}

import Test._
import language.postfixOps

val delete = y
val force  = n

val res1 = "my first string"   y
val res2 = "my second string"  n

Notice how you can import postfixOps and then just add extra whitespace to align all the ys and ns for your string configuration options into the same column.

I'm not sure if this makes sense, but I wrote the above code such that you should be able to use any type (not just strings) for the options with the y and n postfix operators. All you have to do to enable a new type is create an implicit DefaultConfigValue for that type so that the no option has something to return.

OTHER TIPS

I'd strongly recommend against using this pattern, as it violates the principle of least surprise.

StringOps already defines apply(n) on a String to return the Nth character, any other overload is going to confuse a lot of people. Even in the context of a DSL.

Option is also a well-understood term, whose meaning is overloaded here.

Finally: x is very commonly used as a parameter to methods and as a bound value in pattern-matching. Using it in a wide scope like this is going to cause a lot of shadowing, and risks causing some very unexpected error messages.

Can you give a better idea of what you're trying to achieve so that we can suggest some better alternatives?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top