Skip to content
Skillv1.0.0

scala-expert

Expert-level Scala, functional programming, Akka, and reactive systems. Use when the user mentions functional programming, Akka, Cats, or ZIO, or when the task involves Scala Fundamentals, Reactive Sy

by personamanagmentlayer(0) 0 installs
Free
Sign in to install

Free account. Installing gives you the manifest plus copy-paste snippets.

See reviews

About

Imported from personamanagmentlayer/pcl (stdlib/languages/scala-expert/SKILL.md). Install upstream with npx skills add personamanagmentlayer/pcl --skill scala-expert. Copyright stays with the author.

Scala Expert

Expert guidance for Scala development, functional programming, Akka actors, and reactive systems.

Core Concepts

Scala Fundamentals

  • Immutability
  • Pattern matching
  • Case classes
  • Traits and mixins
  • Implicit conversions
  • For comprehensions

Functional Programming

  • Higher-order functions
  • Monads (Option, Either, Try)
  • Functors and Applicatives
  • Type classes
  • Pure functions
  • Referential transparency

Reactive Systems

  • Akka actors
  • Akka Streams
  • Akka HTTP
  • Play Framework
  • Cats Effect
  • ZIO

Scala Basics

// Case classes
case class User(id: String, name: String, email: String, age: Int)

// Pattern matching
def processUser(user: User): String = user match {
  case User(_, name, _, age) if age < 18 => s"$name is a minor"
  case User(_, name, _, age) if age >= 65 => s"$name is a senior"
  case User(_, name, _, _) => s"$name is an adult"
}

// Options instead of null
def findUser(id: String): Option[User] = {
  database.get(id)
}

val userName = findUser("123") match {
  case Some(user) => user.name
  case None => "Unknown"
}

// Or using map
val name = findUser("123").map(_.name).getOrElse("Unknown")

// For comprehensions
def getUserWithPosts(userId: String): Option[(User, List[Post])] = {
  for {
    user <- findUser(userId)
    posts <- findPosts(userId)
  } yield (user, posts)
}

// Traits and mixins
trait Serializable {
  def toJson: String
}

trait Loggable {
  def log(message: String): Unit = println(s"[LOG] $message")
}

case class Person(name: String, age: Int) extends Serializable with Loggable {
  def toJson: String = s"""{"name":"$name","age":$age}"""
}

// Implicit classes (extension methods)
implicit class StringOps(s: String) {
  def isValidEmail: Boolean = s.contains("@") && s.contains(".")
}

"test@example.com".isValidEmail // true

Functional Programming

import cats._
import cats.implicits._

// Functor
val numbers = List(1, 2, 3, 4, 5)
val doubled = numbers.map(_ * 2)

// Applicative
val result = (Option(1), Option(2), Option(3)).mapN { (a, b, c) =>
  a + b + c
}

// Monad (flatMap)
def fetchUser(id: String): Future[Option[User]] = ???
def fetchPosts(userId: String): Future[List[Post]] = ???

val userWithPosts: Future[Option[(User, List[Post])]] = {
  fetchUser("123").flatMap {
    case Some(user) =>
      fetchPosts(user.id).map(posts => Some((user, posts)))
    case None =>
      Future.successful(None)
  }
}

// Or with for-comprehension
val result: Future[Option[(User, List[Post])]] = for {
  userOpt <- fetchUser("123")
  posts <- fetchPosts(userOpt.map(_.id).getOrElse(""))
} yield userOpt.map(user => (user, posts))

// Either for error handling
sealed trait Error
case class NotFound(id: String) extends Error
case class ValidationError(message: String) extends Error

def validateUser(user: User): Either[Error, User] = {
  if (user.email.isValidEmail) Right(user)
  else Left(ValidationError("Invalid email"))
}

def saveUser(user: User): Either[Error, User] = {
  for {
    validated <- validateUser(user)
    saved <- database.save(validated)
  } yield saved
}

// Type classes
trait Show[A] {
  def show(a: A): String
}

object Show {
  def apply[A](implicit sh: Show[A]): Show[A] = sh

  implicit val stringShow: Show[String] = new Show[String] {
    def show(s: String): String = s
  }

  implicit val intShow: Show[Int] = new Show[Int] {
    def show(i: Int): String = i.toString
  }

  implicit def listShow[A: Show]: Show[List[A]] = new Show[List[A]] {
    def show(list: List[A]): String = {
      list.map(Show[A].show).mkString("[", ", ", "]")
    }
  }
}

def print[A: Show](a: A): Unit = {
  println(Show[A].show(a))
}

Akka Actors

import akka.actor.typed._
import akka.actor.typed.scaladsl._

// Actor definition
object UserActor {
  sealed trait Command
  final case class GetUser(id: String, replyTo: ActorRef[Response]) extends Command
  final case class CreateUser(user: User, replyTo: ActorRef[Response]) extends Command

  sealed trait Response
  final case class UserFound(user: User) extends Response
  final case class UserNotFound(id: String) extends Response
  final case class UserCreated(user: User) extends Response

  def apply(): Behavior[Command] = {
    Behaviors.setup { context =>
      var users = Map.empty[String, User]

      Behaviors.receiveMessage {
        case GetUser(id, replyTo) =>
          users.get(id) match {
            case Some(user) =>
              replyTo ! UserFound(user)
            case None =>
              replyTo ! UserNotFound(id)
          }
          Behaviors.same

        case CreateUser(user, replyTo) =>
          users = users + (user.id -> user)
          replyTo ! UserCreated(user)
          Behaviors.same
      }
    }
  }
}

// Using the actor
val system: ActorSystem[UserActor.Command] =
  ActorSystem(UserActor(), "user-system")

import akka.actor.typed.scaladsl.AskPattern._
import akka.util.Timeout
import scala.concurrent.duration._

implicit val timeout: Timeout = 3.seconds

val response: Future[UserActor.Response] =
  system.ask(ref => UserActor.GetUser("123", ref))

Akka Streams

import akka.stream._
import akka.stream.scaladsl._
import akka.actor.ActorSystem

implicit val system = ActorSystem("streams")
implicit val materializer = ActorMaterializer()

// Simple stream
val source = Source(1 to 10)
val flow = Flow[Int].map(_ * 2)
val sink = Sink.foreach[Int](println)

source.via(flow).runWith(sink)

// Backpressure handling
val throttled = Source(1 to 100)
  .throttle(10, 1.second)
  .map { n =>
    println(s"Processing $n")
    n * 2
  }
  .runWith(Sink.ignore)

// Error handling
val resilient = Source(1 to 10)
  .map { n =>
    if (n == 5) throw new Exception("Error at 5")
    n * 2
  }
  .recover {
    case e: Exception => -1
  }
  .runWith(Sink.seq)

// Parallelism
val parallel = Source(1 to 100)
  .mapAsync(parallelism = 4) { n =>
    Future {
      // Async operation
      Thread.sleep(100)
      n * 2
    }
  }
  .runWith(Sink.seq)

Akka HTTP

import akka.http.scaladsl.Http
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
import spray.json.DefaultJsonProtocol._

// JSON protocol
case class User(id: String, name: String, email: String)

object JsonProtocol {
  implicit val userFormat = jsonFormat3(User)
}

import JsonProtocol._

// Routes
val routes =
  pathPrefix("api") {
    pathPrefix("users") {
      get {
        path(Segment) { userId =>
          // GET /api/users/:userId
          complete(findUser(userId))
        } ~
        pathEnd {
          // GET /api/users
          complete(getAllUsers())
        }
      } ~
      post {
        pathEnd {
          // POST /api/users
          entity(as[User]) { user =>
            complete(createUser(user))
          }
        }
      }
    }
  }

// Start server
val bindingFuture = Http().newServerAt("localhost", 8080).bind(routes)

Cats Effect / ZIO

import cats.effect._
import cats.effect.implicits._

// Pure functional effects with Cats Effect
def fetchUser(id: String): IO[User] = IO {
  // Effectful computation
  database.get(id)
}

def saveUser(user: User): IO[Unit] = IO {
  database.save(user)
}

val program: IO[Unit] = for {
  user <- fetchUser("123")
  updated = user.copy(name = "Updated")
  _ <- saveUser(updated)
} yield ()

// Error handling
val safeProgram: IO[Either[Throwable, Unit]] = program.attempt

// Parallel execution
val parallel: IO[List[User]] = {
  List("1", "2", "3")
    .parTraverse(id => fetchUser(id))
}

// ZIO
import zio._

def fetchUserZIO(id: String): Task[User] = ZIO.attempt {
  database.get(id)
}

val zioProgram: Task[Unit] = for {
  user <- fetchUserZIO("123")
  _ <- Console.printLine(s"Found user: ${user.name}")
} yield ()

Best Practices

Functional Programming

  • Prefer immutability
  • Use pure functions
  • Avoid side effects
  • Use Option/Either over null/exceptions
  • Leverage type classes
  • Use for-comprehensions
  • Apply functional composition

Scala Style

  • Follow naming conventions
  • Use case classes for data
  • Prefer vals over vars
  • Use pattern matching
  • Avoid null
  • Use implicits carefully
  • Write idiomatic code

Performance

  • Use lazy evaluation
  • Stream large datasets
  • Avoid unnecessary allocations
  • Use tail recursion
  • Profile before optimizing
  • Consider parallelism

Anti-Patterns

❌ Using null ❌ Mutable state everywhere ❌ God objects ❌ Excessive implicits ❌ Not handling errors ❌ Blocking operations ❌ Not using type safety

Resources

Use it

Copy one of these into your project. Installing also returns the manifest and these snippets.

yaml
targets:
  - https://api.opensmartroute.ai/api/v1/registry/personamanagmentlayer-pcl-scala-expert/manifest   # or paste the manifest below

Manifest

An Open Capability Manifest: the router reads it to know what this does, what it costs and when to pick it.

personamanagmentlayer-pcl-scala-expert.ocm.jsonjson
{
  "ocm": "1",
  "id": "personamanagmentlayer-pcl-scala-expert",
  "kind": "skill",
  "name": "scala-expert",
  "description": "Expert-level Scala, functional programming, Akka, and reactive systems. Use when the user mentions functional programming, Akka, Cats, or ZIO, or when the task involves Scala Fundamentals, Reactive Systems, or Scala Style.",
  "publisher": "personamanagmentlayer",
  "version": "1.0.0",
  "capabilities": {
    "domains": [
      "general"
    ],
    "tags": [
      "skill-md",
      "scala",
      "functional-programming",
      "akka",
      "cats",
      "zio",
      "skills-sh"
    ],
    "languages": [
      "en"
    ]
  },
  "quality_prior": 0.6,
  "examples": [
    "Expert-level Scala, functional programming, Akka, and reactive systems. Use when the user mentions functional programming, Akka, Cats, or ZIO, or when the task involves Scala Fundamentals, Reactive Systems, or Scala Style."
  ],
  "primary": false,
  "metadata": {
    "source": {
      "provider": "skills.sh",
      "repository": "https://github.com/personamanagmentlayer/pcl",
      "path": "stdlib/languages/scala-expert/SKILL.md",
      "ref": "HEAD",
      "url": "https://github.com/personamanagmentlayer/pcl/blob/HEAD/stdlib/languages/scala-expert/SKILL.md",
      "key": "personamanagmentlayer/pcl/stdlib/languages/scala-expert/SKILL.md"
    },
    "allowed_tools": [
      "Read",
      "Write",
      "Edit",
      "Bash(scala:*, sbt:*)"
    ]
  },
  "instructions": "# Scala Expert\n\nExpert guidance for Scala development, functional programming, Akka actors, and reactive systems.\n\n## Core Concepts\n\n### Scala Fundamentals\n\n- Immutability\n- Pattern matching\n- Case classes\n- Traits and mixins\n- Implicit conversions\n- For comprehensions\n\n### Functional Programming\n\n- Higher-order functions\n- Monads (Option, Either, Try)\n- Functors and Applicatives\n- Type classes\n- Pure functions\n- Referential transparency\n\n### Reactive Systems\n\n- Akka actors\n- Akka Streams\n- Akka HTTP\n- Play Framework\n- Cats Effect\n- ZIO\n\n## Scala Basics\n\n```scala\n// Case classes\ncase class Use",
  "cost": {
    "context_tokens": 2198
  }
}

Fetch it by URL: GET /api/v1/registry/personamanagmentlayer-pcl-scala-expert/manifest?version=1.0.0

Reviews

Star ratings from people who tried it. One review per account; edit yours any time.

No reviews yet. Install it, try it, and be the first to rate it.