Home > Blockchain >  Apply function on method parameter
Apply function on method parameter

Time:09-24

I need to update a field in a method which is called from many places. I want all values which are given to the field to be uppercase. But I don't want to transform it inside the methods where it's required. And don't want to create another value. I'm asking if I can use a type of implicits to transform the value?

def parent(itemType: String) =
   getValue(itemType.toUperCase)

or

def parent(itemType: String) = 
   getValue(itemType)

getValue(itemType: String) = {
  val formattedValue = itemType.toUperCase
}

I want to avoid both approaches, and ask for something like:

getValue(itemType: String = itemType.toUperCase) = { 
   // use itemType as upercase value
}

CodePudding user response:

The best thing would be to reify the uppercaseness in the type system.

import scala.language.implicitConversions

object Refined {
  class UppercaseString private[Refined](override val toString: String) extends AnyVal

  implicit def stringToUpper(s: String): UppercaseString = new UppercaseString(s.toUpperCase)

  implicit def upperToString(ucs: UppercaseString): String = ucs.toString
}

Then you can express that a string must be uppercase (and transparently make a regular string uppercase) with

import Refined._

def getValue(itemType: UppercaseString) = ???

The presence of the implicit conversion to UppercaseString means that, as long as Refined.stringToUpper has been imported, we can call getValue with arbitrary strings.

Because UppercaseString extends AnyVal, in many cases it will have no overhead beyond the uppercased string. Since it's a type, calling code can save it as an UppercaseString and save calls to toUpperCase.

Note that implicit class doesn't work here as we want to perform an operation in the process of "construction"; the constructor of UppercaseString is private to Refined so that we can ensure that all creation goes through toUpperCase.

  • Related