소스 정보
- 저장소
- cxcscmu/SkillLearnBench
- 최근 소스 활동
- 2026년 4월 24일 05:14
- 감지된 SKILL.md 언어
- 영어
- 스타
- 77
- 포크
- 4
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/cxcscmu/SkillLearnBench --skill scala-circe-json명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SOC 직업 분류 기준
SKILL.md 표시 중
| name | scala-circe-json |
| description | Working with Circe JSON library in Scala for type-safe JSON processing |
Circe is the standard type-safe JSON library in Scala. It provides:
Json typeAdd to build.sbt:
libraryDependencies ++= Seq(
"io.circe" %% "circe-core" % "0.14.5",
"io.circe" %% "circe-parser" % "0.14.5",
"io.circe" %% "circe-generic" % "0.14.5"
)
import io.circe.parser._
import io.circe._
// Parse from string
val jsonString = """{"name": "Alice", "age": 30}"""
val result: Either[io.circe.ParsingFailure, Json] = parse(jsonString)
// Safe extraction
result match {
case Right(json) => println(s"Parsed: $json")
case Left(error) => println(s"Parse error: $error")
}
// Or with Try
val json: scala.util.Try[Json] = parse(jsonString).toTry
import io.circe.syntax._
// From primitives
val str = Json.fromString("hello")
val num = Json.fromInt(42)
val bool = Json.fromBoolean(true)
val null_val = Json.Null
// Object (using syntax extension)
val obj = Json.obj(
"name" -> Json.fromString("Alice"),
"age" -> Json.fromInt(30)
)
// Array
val arr = Json.arr(
Json.fromInt(1),
Json.fromInt(2),
Json.fromInt(3)
)
// Using tuple extension (cleaner)
val obj = Json.obj(
"name" -> "Alice".asJson,
"age" -> 30.asJson,
"scores" -> List(90, 85, 88).asJson
)
val json = Json.obj(
"name" -> "Alice".asJson,
"age" -> 30.asJson
)
// Type checks
json.isObject // true
json.isArray // false
json.isNull // false
// Conversions
json.asObject // Option[JsonObject]
json.asArray // Option[Vector[Json]]
json.asString // Option[String]
json.asNumber // Option[JsonNumber]
json.asBoolean // Option[Boolean]
// Unsafe conversion (throws)
json.asObject.get
Cursors provide safe, composable navigation (like XPath):
import io.circe.{Json, HCursor}
val json = parse("""
{
"person": {
"name": "Alice",
"addresses": [
{"city": "NYC"},
{"city": "Boston"}
]
}
}
""").getOrElse(Json.Null)
// Creating cursor
val cursor: HCursor = json.hcursor
// Navigation
val name: Either[DecodingFailure, String] =
cursor
.downField("person")
.downField("name")
.as[String]
// Navigate arrays
val firstCity: Either[DecodingFailure, String] =
cursor
.downField("person")
.downField("addresses")
.downArray
.downField("city")
.as[String]
// Optional navigation (returns Json)
cursor.downField("person").downField("name").focus // Option[Json]
val cursor = json.hcursor
// Navigation
cursor.downField("fieldName") // Navigate to field
cursor.downArray // Navigate to first array element
cursor.up // Go to parent
cursor.left // Move to previous array element
cursor.right // Move to next array element
// Extraction
cursor.focus // Option[Json] - current value
cursor.as[String] // Either[DecodingFailure, String]
// Checking
cursor.succeeded // Boolean - did navigation succeed?
import io.circe._, io.circe.generic.semiauto._
case class Person(name: String, age: Int)
// Automatic codec generation
implicit val encoder: Encoder[Person] = deriveEncoder[Person]
implicit val decoder: Decoder[Person] = deriveDecoder[Person]
// Usage
val person = Person("Alice", 30)
val json = person.asJson
val decoded = json.as[Person] // Either[DecodingFailure, Person]
implicit val customEncoder: Encoder[Person] = new Encoder[Person] {
def apply(p: Person): Json = Json.obj(
"fullName" -> Json.fromString(p.name),
"years" -> Json.fromInt(p.age)
)
}
implicit val customDecoder: Decoder[Person] = new Decoder[Person] {
def apply(c: HCursor): Decoder.Result[Person] = for {
name <- c.downField("fullName").as[String]
age <- c.downField("years").as[Int]
} yield Person(name, age)
}
For recursive types like JSON itself:
// Representing JSON recursively
sealed trait JsonValue
case class JString(value: String) extends JsonValue
case class JNumber(value: Double) extends JsonValue
case class JBoolean(value: Boolean) extends JsonValue
case object JNull extends JsonValue
case class JArray(value: Vector[JsonValue]) extends JsonValue
case class JObject(value: Map[String, JsonValue]) extends JsonValue
// Or use Circe's Json type directly (which IS recursive)
val json: Json = Json.obj(
"data" -> Json.arr(
Json.obj("id" -> 1.asJson),
Json.obj("id" -> 2.asJson)
)
)
import io.circe.Printer
val json = Json.obj("name" -> "Alice".asJson, "age" -> 30.asJson)
// Compact
json.toString()
// {"name":"Alice","age":30}
// Pretty printed
val printer = Printer.spaces2 // 2-space indent
println(printer.print(json))
// {
// "name" : "Alice",
// "age" : 30
// }
// Custom printer
val customPrinter = Printer(
dropNullValues = false,
indent = " "
)
def getValueAtPath(json: Json, path: String): Option[Json] = {
val parts = path.split("\\.")
parts.foldLeft(Option(json)) { case (current, part) =>
current.flatMap { j =>
if (j.isObject) {
j.hcursor.downField(part).focus
} else if (j.isArray) {
part.toIntOption.flatMap { idx =>
j.asArray.flatMap(_.lift(idx))
}
} else {
None
}
}
}
}
// Usage
val json = parse("""{"person": {"name": "Alice", "scores": [90, 85]}}""").getOrElse(Json.Null)
val name = getValueAtPath(json, "person.name") // Some("Alice")
val score = getValueAtPath(json, "person.scores.0") // Some(90)
val missing = getValueAtPath(json, "person.email") // None
import io.circe.Json
import io.circe.syntax._
class JsonTokenizer(pretty: Boolean = false) {
def tokenize(json: Json): Token = {
val jsonStr = if (pretty) {
Printer.spaces2.print(json)
} else {
json.toString()
}
Token(jsonStr, TokenType.STRUCTURED, Map("json" -> true.asJson))
}
def tokenizePath(json: Json, path: String): Option[Token] = {
getValueAtPath(json, path).map(tokenize)
}
private def getValueAtPath(json: Json, path: String): Option[Json] = {
val parts = path.split("\\.")
parts.foldLeft(Option(json)) { case (current, part) =>
current.flatMap { j =>
if (j.isObject) j.hcursor.downField(part).focus
else if (j.isArray) {
part.toIntOption.flatMap(idx => j.asArray.flatMap(_.lift(idx)))
} else None
}
}
}
}
Unlike Python's duck typing with JSON:
# Python - runtime errors possible
data = {"name": "Alice"}
age = data["age"] # KeyError!
// Scala - compile-time safety
val json = parse("""{"name": "Alice"}""").getOrElse(Json.Null)
val age: Option[Int] = json.hcursor.downField("age").as[Int].toOption
// Type mismatch caught at compile time
// Manual approach (error-prone)
val jsonStr = s"""{"value": "$value", "type": "$tokenType"}"""
// Circe approach (safe, composable)
val token = Token(value, tokenType)
val json = token.asJson // With derived encoders