score:1
if you really wanted to, you could have something typeclass-based:
def convert[i, o](in: i)(implicit c: conversionrule[i, o]): o = {
if (c.isconvertible(in)) c.convert(in)
else c.zero
}
trait conversionrule[i, o] {
def isconvertible(in: i): boolean
def convert(in: i): o
def zero: o // could possibly derive the zero from, e.g., a cats monoid instance where such exists
}
the eagle-eyed may notice that the isconvertible
/convert
methods match the contract of partialfunction[i, o]
's isdefinedat
/apply
, so may as well just use partialfunction
(and rewrite convert
with isdefinedat
/apply
)
trait conversionrule[i, o] extends partialfunction[i, o] {
def zero: o
}
zero
can be implemented in terms of partialfunction.applyorelse
, but for the case where zero
is constant (which is the case where referential transparency is preserved), this is much faster.
smart constructors can be defined:
object conversionrule {
def apply[i, o](zerovalue: o)(pf: partialfunction[i, o]): conversionrule[i, o] =
new conversionrule[i, o] {
override def apply(i: i): o = pf(i)
override def isdefinedat(i: i): boolean = pf.isdefinedat(i)
val zero: o = zerovalue
}
def totalconversion[i, o](f: i => o): conversionrule[i, o] =
new conversionrule[i, o] {
override def apply(i: i) = f(i)
override def isdefinedat(i: i) = true
override def zero: o = throw new assertionerror("should not call since conversion is defined")
}
// might want to put this in a `lowpriorityimplicits` trait which this object extends
implicit def identityconversion[i]: conversionrule[i, i] =
totalconversion(identity)
}
identityconversion
means that a convertinttoint
gets automatically generated.
convertstringtoint
can then be defined as
implicit val stringtointconversion = conversionrule[string, int](0) {
case x if x.forall(_.isdigit) => x.toint
}
one can define a tostring
based conversion (basically the non-lawful show
proposed for alleycats):
implicit def generictostring[i]: conversionrule[i, string] =
conversionrule.totalconversionrule(_.tostring)
and it should then be possible to define a stringviaint
conversionrule
derivation like:
implicit def stringviaint[i, o](implicit toint: conversionrule[i, int]): conversionrule[i, string] =
convert(convert(in)(toint))
the only really useful thing this provides is an opt-in to usage of implicit conversions. whether that's enough of a gain to justify? shrug
(disclaimer: only the scala compiler in my head has attempted to compile this)
Source: stackoverflow.com
Related Query
- generalize Int -> Int, Int-> String, String -> String, String -> Int
- How to convert an Int to a String of a given length with leading zeros to align?
- Scala: convert string to Int or None
- Spark Scala: Cannot up cast from string to int as it may truncate
- Scala String toInt - Int does not take parameters
- Implicit conversion from String to Int in scala 2.8
- Int vs Integer: type mismatch, found: Int, required: String
- Cast Any of String to Int
- How to convert string array to int array in scala
- Decode case class, String or Int in circe
- Scala int value of String characters
- Why can I concatenate String and Int in Scala?
- Type mismatch, found Int required String
- Scala accept only String or Int generic case class in List
- String to Int in Scala
- Difference between matching String and Int in Scala
- Adding an Int to a String in scala
- List[Int] => Int without String Conversion?
- How expensive is String to Int to String conversion in Scala?
- Scala: Why the Int type list contains String as well?
- Play 2 Json format, capture Int or String
- Casting String to Int using scala extractors
- Converting String RDD to Int RDD
- Spark comparing boolean column with string column works differently to comparing int and string where values are equal
- How to change String to Int in Json Parser in scala
- What is the idiomatic way of making a String from two Int in Scala?
- List string int converting in scala
- Parsing a String to Boolean or Int
- play framework type mismatch; found : Int required: String
- Generate Int mapping for String in List
More Query from same tag
- In Spark's interactive shell, how to integrate conf param in spark context?
- scala matching optional set of characters
- Implicit class in scala not showing output as expected
- Spark Streaming - java.lang.NoSuchMethodError Error
- Spark code to find maximum not working
- Companion Object Attributes Initialization in Scala
- How to create encoder for Option type constructor, e.g. Option[Int]?
- How to set up jacoco4sbt to process classes in main and submodules in Play?
- Squeryl dynamic join clauses
- How to add new column when create a csv file in scala
- Read Impala tables and column names from Spark job
- Scala, Sbt - download wrong version of library even if it is set in build.sbt
- spark use underscore as parameter to RDD.flatmap or map
- Idiomatic way to find a matching line in Scala
- Scala error: Found List[Char], required List[ScalaObject]
- It is not possible to call static methods of Java classes continuously in scala
- How to explode column with multiple records into multiple Columns in Spark
- Scala : How to wait between map/foreach iteration?
- Scala generics for generic type
- Get the vertex with highest degree of a large graph in GraphX
- Unable to install scala
- Spark : converting Array[Byte] data to RDD or DataFrame
- SBT Native Packager: Build the same package with different configs
- How to read orc data source in spark structured streaming?
- covariance issue using shapeless
- Runtime type checks / pattern matching involving variable arity types
- How can I easily get a Scala case class's name?
- Ambiguous overloading: fix it or try something else?
- Scala Spark execution of RDD contiguous subsets
- Scala - Spray.io - sbt-revolver - jrebel - Not seeing changes to HttpService (or anything) on reload