scalaadvanced
Context Functions and Capability Pattern
Use Scala 3 context functions for dependency injection, capability passing, and builder DSLs.
scalaPress ⌘/Ctrl + Shift + C to copy
import scala.collection.mutable.ListBuffer
// Context function type: A ?=> B
trait Logger:
def log(msg: String): Unit
class ConsoleLogger(prefix: String) extends Logger:
def log(msg: String): Unit = println(s"[$prefix] $msg")
// Context function
type Logged[T] = Logger ?=> T
def doWork(input: String): Logged[String] =
summon[Logger].log(s"Processing: $input")
val result = input.toUpperCase
summon[Logger].log(s"Result: $result")
result
def pipeline(data: List[String]): Logged[List[String]] =
summon[Logger].log(s"Pipeline started with ${data.size} items")
val results = data.map(doWork)
summon[Logger].log(s"Pipeline completed")
results
// Builder DSL with context functions
class HtmlBuilder:
private val buffer = ListBuffer[String]()
private var indent = 0
def tag(name: String)(content: HtmlBuilder ?=> Unit): Unit =
buffer += s"${" " * indent}<$name>"
indent += 2
content(using this)
indent -= 2
buffer += s"${" " * indent}</$name>"
def text(s: String): Unit =
buffer += s"${" " * indent}$s"
def result: String = buffer.mkString("\n")
def html(build: HtmlBuilder ?=> Unit): String =
val builder = HtmlBuilder()
build(using builder)
builder.result
// Transaction context
trait Transaction:
def execute(sql: String): Unit
def rollback(): Unit
class DbTransaction extends Transaction:
private val executed = ListBuffer[String]()
def execute(sql: String): Unit =
println(s" SQL: $sql")
executed += sql
def rollback(): Unit =
println(s" Rolling back ${executed.size} operations")
executed.clear()
type Transactional[T] = Transaction ?=> T
def insertUser(name: String): Transactional[Unit] =
summon[Transaction].execute(s"INSERT INTO users VALUES ('$name')")
def insertOrder(userId: String, amount: Double): Transactional[Unit] =
summon[Transaction].execute(
s"INSERT INTO orders VALUES ('$userId', $amount)"
)
def transferFunds(from: String, to: String, amount: Double): Transactional[Unit] =
summon[Transaction].execute(s"UPDATE accounts SET balance = balance - $amount WHERE id = '$from'")
summon[Transaction].execute(s"UPDATE accounts SET balance = balance + $amount WHERE id = '$to'")
@main def run(): Unit =
// Logger context
given Logger = ConsoleLogger("APP")
val result = pipeline(List("hello", "world", "scala"))
println(s"Results: $result")
// HTML DSL
val page = html {
summon[HtmlBuilder].tag("html") {
summon[HtmlBuilder].tag("body") {
summon[HtmlBuilder].tag("h1") {
summon[HtmlBuilder].text("Hello, Scala 3!")
}
summon[HtmlBuilder].tag("p") {
summon[HtmlBuilder].text("Context functions are powerful.")
}
}
}
}
println(page)
// Transaction context
given Transaction = DbTransaction()
println("Running transaction:")
insertUser("alice")
insertOrder("alice", 99.99)
transferFunds("alice", "bob", 50.0)Use Cases
- Dependency injection without frameworks
- Builder DSLs with implicit context
- Transaction management patterns
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
scalaadvanced
DSL Builder Pattern
Create type-safe domain-specific languages with Scala's builder pattern using apply and infix notation.
Best for: Type-safe query builders
#scala#dsl
scalaintermediate
Custom String Interpolation
Create custom string interpolators in Scala: SQL, HTML, JSON, and validated interpolation.
Best for: SQL query building with parameter binding
#scala#string-interpolation
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