scalaintermediate
Implicit Conversions in Scala 3
Use Scala 3 Conversion type class for safe implicit conversions and interop patterns.
scalaPress â/Ctrl + Shift + C to copy
import scala.language.implicitConversions
// Scala 3 Conversion type class
case class Celsius(value: Double)
case class Fahrenheit(value: Double)
case class Kelvin(value: Double)
given Conversion[Celsius, Fahrenheit] with
def apply(c: Celsius): Fahrenheit =
Fahrenheit(c.value * 9.0 / 5.0 + 32)
given Conversion[Fahrenheit, Celsius] with
def apply(f: Fahrenheit): Celsius =
Celsius((f.value - 32) * 5.0 / 9.0)
given Conversion[Celsius, Kelvin] with
def apply(c: Celsius): Kelvin =
Kelvin(c.value + 273.15)
// Duration conversions
case class Seconds(value: Double)
case class Minutes(value: Double)
case class Hours(value: Double)
given Conversion[Minutes, Seconds] with
def apply(m: Minutes): Seconds = Seconds(m.value * 60)
given Conversion[Hours, Seconds] with
def apply(h: Hours): Seconds = Seconds(h.value * 3600)
given Conversion[Hours, Minutes] with
def apply(h: Hours): Minutes = Minutes(h.value * 60)
// Java interop conversions
import java.util.{List as JList, Map as JMap, Optional}
import scala.jdk.CollectionConverters.*
extension [T](opt: Optional[T])
def toScala: Option[T] =
if opt.isPresent then Some(opt.get()) else None
extension [T](opt: Option[T])
def toJava: Optional[T] = opt match
case Some(v) => Optional.of(v)
case None => Optional.empty()
// Numeric conversions with validation
object SafeConversions:
opaque type PositiveInt = Int
object PositiveInt:
def apply(n: Int): Option[PositiveInt] =
if n > 0 then Some(n) else None
extension (p: PositiveInt)
def value: Int = p
given Conversion[PositiveInt, Int] with
def apply(p: PositiveInt): Int = p
@main def run(): Unit =
// Temperature
val boiling: Celsius = Celsius(100)
val boilingF: Fahrenheit = boiling // automatic conversion
val boilingK: Kelvin = boiling
println(f"${boiling.value}°C = ${boilingF.value}%.1f°F = ${boilingK.value}%.2fK")
val bodyTemp: Fahrenheit = Fahrenheit(98.6)
val bodyCelsius: Celsius = bodyTemp
println(f"${bodyTemp.value}°F = ${bodyCelsius.value}%.1f°C")
// Duration
def processWithTimeout(timeout: Seconds): Unit =
println(f"Timeout: ${timeout.value}%.0f seconds")
processWithTimeout(Minutes(5)) // auto-converted to 300 seconds
processWithTimeout(Hours(1)) // auto-converted to 3600 seconds
// Java interop
val jOptional = Optional.of("hello")
val scalaOption: Option[String] = jOptional.toScala
println(s"Optional -> Option: $scalaOption")
val back: Optional[String] = scalaOption.toJava
println(s"Option -> Optional: $back")Use Cases
- Unit conversion libraries
- Java-Scala interop
- Domain type conversions
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
scalabeginner
Java Interop and Collections
Work with Java libraries from Scala: collection conversions, null safety, and API wrapping.
Best for: Using Java libraries from Scala
#scala#java
scalabeginner
Type Conversions and Safe Casting
Convert between types safely: numeric conversions, asInstanceOf alternatives, and pattern-based casting.
Best for: Safe data type conversions
#scala#types
scalabeginner
Scala Hello World Application
Create a basic Scala application with main method, string interpolation, and val/var basics.
Best for: Getting started with Scala
#scala#basics
scalabeginner
Pattern Matching Fundamentals
Use Scala pattern matching with guards, type patterns, tuple patterns, and nested extractors.
Best for: Control flow with pattern matching
#scala#pattern-matching