Spaces:
Paused
Paused
File size: 4,583 Bytes
93d826e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | package example
import scala.concurrent.{Future, ExecutionContext}
import scala.util.{Try, Success, Failure}
import scala.collection.mutable
import scala.annotation.tailrec
// Type alias
type Result[T] = Either[String, T]
// Trait with type parameter
trait DataProcessor[T] {
def process(data: T): Result[T]
def validate(data: T): Boolean
}
// Case class with type parameters
case class ProcessingState[T](
data: T,
status: ProcessingState.Status,
timestamp: Long = System.currentTimeMillis()
)
// Companion object with sealed trait
object ProcessingState {
sealed trait Status
case object Pending extends Status
case object Active extends Status
case object Completed extends Status
case class Failed(error: String) extends Status
}
// Abstract class
abstract class BaseProcessor[T] extends DataProcessor[T] {
protected val logger = new Logger(getClass.getName)
// Abstract method
protected def transform(data: T): T
// Concrete implementation using abstract method
override def process(data: T): Result[T] = {
if (!validate(data)) {
Left("Invalid data")
} else {
Try(transform(data)).toEither.left.map(_.getMessage)
}
}
}
// Class with type bounds
class NumberProcessor[T <: Number] extends BaseProcessor[T] {
override def validate(data: T): Boolean = data != null
protected def transform(data: T): T = data
}
// Case class with default and optional parameters
case class User(
id: String,
name: String,
email: String,
roles: Set[String] = Set.empty,
metadata: Map[String, String] = Map.empty
)
// Object for utility functions
object Utils {
def withRetry[T](times: Int)(f: => T): Try[T] = {
@tailrec
def attempt(remaining: Int, lastError: Option[Throwable]): Try[T] = {
if (remaining == 0) {
Failure(lastError.getOrElse(new RuntimeException("Max retries exceeded")))
} else {
Try(f) match {
case success @ Success(_) => success
case Failure(error) => attempt(remaining - 1, Some(error))
}
}
}
attempt(times, None)
}
}
// Implicit class for extensions
object Implicits {
implicit class StringOps(val s: String) extends AnyVal {
def isValidEmail: Boolean = s.matches(".+@.+\\..+")
}
}
// Trait with self type annotation
trait Logging {
self: Logger =>
def debug(message: => String): Unit = log("DEBUG", message)
def info(message: => String): Unit = log("INFO", message)
def error(message: => String): Unit = log("ERROR", message)
}
// Class using self type trait
class Logger(name: String) extends Logging {
def log(level: String, message: => String): Unit = {
println(s"[$level] $name: $message")
}
}
// Class with type constructor and higher-kinded type
trait Monad[F[_]] {
def pure[A](a: A): F[A]
def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B]
def map[A, B](fa: F[A])(f: A => B): F[B] =
flatMap(fa)(a => pure(f(a)))
}
// Implicit conversions
object Conversions {
implicit def stringToUser(s: String): User = {
val parts = s.split(":")
User(parts(0), parts(1), parts(2))
}
}
// Trait with path-dependent type
trait Container {
type Content
def content: Content
def transform(f: Content => Content): Container
}
// Class implementing path-dependent type
class Box[T](initial: T) extends Container {
type Content = T
def content: T = initial
def transform(f: T => T): Box[T] = new Box(f(initial))
}
// Main object with application
object Main extends App {
import Implicits._
import ExecutionContext.Implicits.global
val processor = new NumberProcessor[java.lang.Integer]
def processAsync[T](data: T)(implicit ec: ExecutionContext): Future[Result[T]] = {
Future {
Thread.sleep(100) // Simulate work
Right(data)
}
}
// Pattern matching
def handleResult[T](result: Result[T]): Unit = result match {
case Right(value) => println(s"Success: $value")
case Left(error) => println(s"Error: $error")
}
// For comprehension
val computation = for {
a <- Future(1)
b <- Future(2)
c <- Future(a + b)
} yield c
// Partial function
val handler: PartialFunction[Throwable, Unit] = {
case e: IllegalArgumentException => println(s"Invalid argument: ${e.getMessage}")
case e: Exception => println(s"Other error: ${e.getMessage}")
}
// Using implicit conversion
val user: User = "1:John Doe:john@example.com"
// Using type class
val box = new Box(42)
val transformed = box.transform(_ * 2)
println(s"Transformed value: ${transformed.content}")
}
|