[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6KFV1G54FQ26PV44DXDY072":3,"skill-same:01M6KFV1G54FQ26PV44DXDY072":58},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":31,"linkOnly":32,"markdownContent":33,"markdownBody":34,"frontMatter":35,"refName":36,"commitSha":37,"skillDirectory":38,"forksCount":39,"repositoryHtmlUrl":40,"repositoryHomepageUrl":41,"ownerHtmlUrl":42,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":43,"install":44,"resources":57},"01M6KFV1G54FQ26PV44DXDY072","run2_scala-builder",null,"Implementing an immutable fluent builder in Scala with companion object apply, varargs metadata, and a build() method returning a function — translating Python's mutable builder class.","cxcscmu\u002FSkillLearnBench","cxcscmu","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F142838272?v=4","01M6KCQDFQWPDSN0MKZY96MSQP","01M6KCQDM7G70TKJ28NTSQC0RZ",93,"MIT","https:\u002F\u002Fgithub.com\u002Fcxcscmu\u002FSkillLearnBench\u002Fblob\u002Fmain\u002Fskills\u002Fb2-self-feedback-claude-sonnet-4-6\u002Fpython-scala-translation\u002Frun2_scala-builder\u002FSKILL.md",[],[18,19,20,21,22,23,24,25,26,27,28,29,30],"scala","builder","run2 scala builder","python","fluent","metadata","immutable","build","with","companion","object","implementing","apply","2026-11-10 10:12:30",false,"---\nname: run2_scala-builder\ndescription: Implementing an immutable fluent builder in Scala with companion object apply, varargs metadata, and a build() method returning a function — translating Python's mutable builder class.\n---\n\n# Scala Immutable Fluent Builder Pattern\n\n## Python Mutable Builder → Scala Immutable Builder\n\nPython accumulates state by mutating lists\u002Fdicts:\n```python\nclass TokenizerBuilder(Generic[T]):\n    def __init__(self):\n        self._normalizers: list[Callable[[str], str]] = []\n        self._validators: list[Callable[[T], bool]] = []\n        self._metadata: dict[str, Any] = {}\n\n    def with_normalizer(self, norm) -> \"TokenizerBuilder[T]\":\n        self._normalizers.append(norm)  # mutates\n        return self\n\n    def build(self) -> Callable[[T], Token]:\n        normalizers = self._normalizers.copy()  # defensive copy needed!\n        ...\n```\n\nScala uses an immutable builder — each `with*` call returns a **new** instance:\n```scala\nfinal class TokenizerBuilder[T] private (\n  normalizers: List[String => String],\n  validators:  List[T => Boolean],\n  meta:        Map[String, Any]\n) {\n  def withNormalizer(f: String => String): TokenizerBuilder[T] =\n    new TokenizerBuilder(normalizers :+ f, validators, meta)    \u002F\u002F creates new instance\n\n  def withValidator(p: T => Boolean): TokenizerBuilder[T] =\n    new TokenizerBuilder(normalizers, validators :+ p, meta)\n\n  def withMetadata(entries: (String, Any)*): TokenizerBuilder[T] =\n    new TokenizerBuilder(normalizers, validators, meta ++ entries.toMap)\n\n  def build(): T => Token = { value =>\n    validators.foreach { v =>\n      if (!v(value)) throw new IllegalArgumentException(s\"Validation failed for $value\")\n    }\n    val str = normalizers.foldLeft(value.toString)((s, norm) => norm(s))\n    Token(str, TokenType.STRING, meta)\n  }\n}\n```\n\n**Benefits of immutable builder:**\n- No defensive copy needed in `build()` — captured state is already immutable\n- Thread-safe by default — no shared mutable state\n- Each intermediate builder is a valid value (can branch\u002Fshare)\n\n## Companion Object for Clean API\n\nPython: `builder = TokenizerBuilder()`\nScala companion:\n```scala\nobject TokenizerBuilder {\n  def apply[T](): TokenizerBuilder[T] =\n    new TokenizerBuilder[T](Nil, Nil, Map.empty)\n}\n```\n\nUsage (calling convention matches Python):\n```scala\nval tokenizer = TokenizerBuilder[String]()   \u002F\u002F apply() invoked implicitly\n  .withNormalizer(_.toLowerCase)\n  .withNormalizer(_.replace(\" \", \"_\"))\n  .withValidator(_.nonEmpty)\n  .withMetadata(\"type\" -> \"custom\")          \u002F\u002F varargs tuple syntax\n  .build()\n\nval token = tokenizer(\"Hello World\")\n\u002F\u002F token.value    == \"hello_world\"\n\u002F\u002F token.metadata == Map(\"type\" -> \"custom\")\n```\n\n## Key Design Choices\n\n| Python                    | Scala                          | Reason                              |\n|---------------------------|--------------------------------|-------------------------------------|\n| Mutable `list.append`     | `list :+ elem` → new list      | Immutability, thread safety          |\n| `**kwargs` in withMetadata| `(String, Any)*` varargs       | Scala convention for map-like params |\n| `dict.update`             | `map ++ other.toMap`           | Immutable map merge                  |\n| `Callable[[T], Token]`    | `T => Token` (function type)   | Scala first-class function type      |\n| `for v in validators`     | `foldLeft` for normalizers     | Functional pipeline                  |\n\n## WhitespaceTokenizer — Practical Tokenizer with Options\n\n```scala\nfinal class WhitespaceTokenizer(\n  lowercase:        Boolean     = false,\n  minLength:        Int         = 0,\n  maxLength:        Option[Int] = None,\n  stripPunctuation: Boolean     = false\n) {\n  private val punctuation: Set[Char] =\n    Set('.', ',', '!', '?', ';', ':', '\\'', '\"', '(', ')', '[', ']', '{', '}')\n\n  \u002F\u002F Python's str.strip(chars) equivalent: drop from both ends\n  private def processWord(word: String): Option[String] = {\n    val stripped =\n      if (stripPunctuation)\n        word.dropWhile(punctuation).reverse.dropWhile(punctuation).reverse\n      else word\n    val lowered = if (lowercase) stripped.toLowerCase else stripped\n    if (lowered.length \u003C minLength) None\n    else {\n      val truncated = maxLength.filter(_ \u003C lowered.length).fold(lowered)(lowered.take)\n      if (truncated.isEmpty) None else Some(truncated)\n    }\n  }\n\n  def tokenize(text: String): List[Token] = {\n    val words = if (text.trim.isEmpty) Array.empty[String] else text.trim.split(\"\\\\s+\")\n    words.zipWithIndex.toList.flatMap { case (word, idx) =>\n      processWord(word).map(Token(_, TokenType.STRING, Map(\"position\" -> idx, \"original\" -> word)))\n    }\n  }\n}\n```\n\n**Python `str.strip(chars)` → Scala pattern:**\n```scala\nword.dropWhile(charSet).reverse.dropWhile(charSet).reverse\n```\nThis correctly removes any characters from `charSet` at both the start and end of the string.\n","# Scala Immutable Fluent Builder Pattern\n\n## Python Mutable Builder → Scala Immutable Builder\n\nPython accumulates state by mutating lists\u002Fdicts:\n```python\nclass TokenizerBuilder(Generic[T]):\n    def __init__(self):\n        self._normalizers: list[Callable[[str], str]] = []\n        self._validators: list[Callable[[T], bool]] = []\n        self._metadata: dict[str, Any] = {}\n\n    def with_normalizer(self, norm) -> \"TokenizerBuilder[T]\":\n        self._normalizers.append(norm)  # mutates\n        return self\n\n    def build(self) -> Callable[[T], Token]:\n        normalizers = self._normalizers.copy()  # defensive copy needed!\n        ...\n```\n\nScala uses an immutable builder — each `with*` call returns a **new** instance:\n```scala\nfinal class TokenizerBuilder[T] private (\n  normalizers: List[String => String],\n  validators:  List[T => Boolean],\n  meta:        Map[String, Any]\n) {\n  def withNormalizer(f: String => String): TokenizerBuilder[T] =\n    new TokenizerBuilder(normalizers :+ f, validators, meta)    \u002F\u002F creates new instance\n\n  def withValidator(p: T => Boolean): TokenizerBuilder[T] =\n    new TokenizerBuilder(normalizers, validators :+ p, meta)\n\n  def withMetadata(entries: (String, Any)*): TokenizerBuilder[T] =\n    new TokenizerBuilder(normalizers, validators, meta ++ entries.toMap)\n\n  def build(): T => Token = { value =>\n    validators.foreach { v =>\n      if (!v(value)) throw new IllegalArgumentException(s\"Validation failed for $value\")\n    }\n    val str = normalizers.foldLeft(value.toString)((s, norm) => norm(s))\n    Token(str, TokenType.STRING, meta)\n  }\n}\n```\n\n**Benefits of immutable builder:**\n- No defensive copy needed in `build()` — captured state is already immutable\n- Thread-safe by default — no shared mutable state\n- Each intermediate builder is a valid value (can branch\u002Fshare)\n\n## Companion Object for Clean API\n\nPython: `builder = TokenizerBuilder()`\nScala companion:\n```scala\nobject TokenizerBuilder {\n  def apply[T](): TokenizerBuilder[T] =\n    new TokenizerBuilder[T](Nil, Nil, Map.empty)\n}\n```\n\nUsage (calling convention matches Python):\n```scala\nval tokenizer = TokenizerBuilder[String]()   \u002F\u002F apply() invoked implicitly\n  .withNormalizer(_.toLowerCase)\n  .withNormalizer(_.replace(\" \", \"_\"))\n  .withValidator(_.nonEmpty)\n  .withMetadata(\"type\" -> \"custom\")          \u002F\u002F varargs tuple syntax\n  .build()\n\nval token = tokenizer(\"Hello World\")\n\u002F\u002F token.value    == \"hello_world\"\n\u002F\u002F token.metadata == Map(\"type\" -> \"custom\")\n```\n\n## Key Design Choices\n\n| Python                    | Scala                          | Reason                              |\n|---------------------------|--------------------------------|-------------------------------------|\n| Mutable `list.append`     | `list :+ elem` → new list      | Immutability, thread safety          |\n| `**kwargs` in withMetadata| `(String, Any)*` varargs       | Scala convention for map-like params |\n| `dict.update`             | `map ++ other.toMap`           | Immutable map merge                  |\n| `Callable[[T], Token]`    | `T => Token` (function type)   | Scala first-class function type      |\n| `for v in validators`     | `foldLeft` for normalizers     | Functional pipeline                  |\n\n## WhitespaceTokenizer — Practical Tokenizer with Options\n\n```scala\nfinal class WhitespaceTokenizer(\n  lowercase:        Boolean     = false,\n  minLength:        Int         = 0,\n  maxLength:        Option[Int] = None,\n  stripPunctuation: Boolean     = false\n) {\n  private val punctuation: Set[Char] =\n    Set('.', ',', '!', '?', ';', ':', '\\'', '\"', '(', ')', '[', ']', '{', '}')\n\n  \u002F\u002F Python's str.strip(chars) equivalent: drop from both ends\n  private def processWord(word: String): Option[String] = {\n    val stripped =\n      if (stripPunctuation)\n        word.dropWhile(punctuation).reverse.dropWhile(punctuation).reverse\n      else word\n    val lowered = if (lowercase) stripped.toLowerCase else stripped\n    if (lowered.length \u003C minLength) None\n    else {\n      val truncated = maxLength.filter(_ \u003C lowered.length).fold(lowered)(lowered.take)\n      if (truncated.isEmpty) None else Some(truncated)\n    }\n  }\n\n  def tokenize(text: String): List[Token] = {\n    val words = if (text.trim.isEmpty) Array.empty[String] else text.trim.split(\"\\\\s+\")\n    words.zipWithIndex.toList.flatMap { case (word, idx) =>\n      processWord(word).map(Token(_, TokenType.STRING, Map(\"position\" -> idx, \"original\" -> word)))\n    }\n  }\n}\n```\n\n**Python `str.strip(chars)` → Scala pattern:**\n```scala\nword.dropWhile(charSet).reverse.dropWhile(charSet).reverse\n```\nThis correctly removes any characters from `charSet` at both the start and end of the string.\n",{"name":5,"description":7},"main","726e1f79b96b0cb3d729d0e55a1c847e0b5353ae","skills\u002Fb2-self-feedback-claude-sonnet-4-6\u002Fpython-scala-translation\u002Frun2_scala-builder",8,"https:\u002F\u002Fgithub.com\u002Fcxcscmu\u002FSkillLearnBench","https:\u002F\u002Fcxcscmu.github.io\u002FSkillLearnBench","https:\u002F\u002Fgithub.com\u002Fcxcscmu","2026-10-02 22:55:36",{"source":8,"skillName":5,"commands":45,"prompt":55,"zipAvailable":56},[46,49,52],{"tool":47,"command":48},"npx","npx skills add cxcscmu\u002FSkillLearnBench --skill run2_scala-builder",{"tool":50,"command":51},"bunx","bunx skills add cxcscmu\u002FSkillLearnBench --skill run2_scala-builder",{"tool":53,"command":54},"pnpm","pnpm dlx skills add cxcscmu\u002FSkillLearnBench --skill run2_scala-builder","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fcxcscmu\u002FSkillLearnBench\u002Fblob\u002Fmain\u002Fskills\u002Fb2-self-feedback-claude-sonnet-4-6\u002Fpython-scala-translation\u002Frun2_scala-builder\u002FSKILL.md",true,[],[59,76,101,119,139,150],{"skillNo":60,"name":61,"nameZh":6,"description":62,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":63,"categories":64,"keywords":70,"publishedAt":31},"01M6KM5KH175P5ABP5JMX2SBDQ","object_counter","Count occurrences of an object in the image using computer vision algorithm.","https:\u002F\u002Fgithub.com\u002Fcxcscmu\u002FSkillLearnBench\u002Fblob\u002Fmain\u002Fskills\u002Fhuman_authored\u002Fvideo-object-counting\u002Fobject_counter\u002FSKILL.md",[65],{"categoryNo":66,"categoryName":67,"taxonomyType":68,"taxonomyTypeDesc":69},"01JBSEEDCAT000000000000016","图像与多媒体","SCENARIO","使用场景",[71,28,72,73,74,75],"object counter","vision","computer","Computer Vision","image",{"skillNo":77,"name":78,"nameZh":6,"description":79,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":80,"categories":81,"keywords":85,"publishedAt":31},"01M6KM51TMVXG79MMPCS6Y8G86","travel-planning-workflow","Invoke this skill when performing travel planning. It defines a structured workflow for generating itineraries. Following this workflow is essential to ensure the final plan satisfies user requirements.","https:\u002F\u002Fgithub.com\u002Fcxcscmu\u002FSkillLearnBench\u002Fblob\u002Fmain\u002Fskills\u002Fhuman_authored\u002Ftravel-planning\u002Ftravel-planning-workflow\u002FSKILL.md",[82],{"categoryNo":83,"categoryName":84,"taxonomyType":68,"taxonomyTypeDesc":69},"01JBSEEDCAT000000000000023","Skill与智能体开发",[86,87,88,89,90,91,92,93,94,95,96,97,98,99,100],"workflow","planning","planning workflow","travel","travel planning","travel planning workflow","structured","performing","plan","for","user","it","requirements","essential","itineraries",{"skillNo":102,"name":103,"nameZh":6,"description":104,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":105,"categories":106,"keywords":107,"publishedAt":31},"01M6KM4DY820XHS9YTSK5QP5HD","bundled-dataset-search-tool","invoke this skill when you need to perform database search for travel planning. This skill provides some useful pre-packaged tools to look up accommodations, attractions, cities, driving distance, flights, and restaurants from the bundled dataset.","https:\u002F\u002Fgithub.com\u002Fcxcscmu\u002FSkillLearnBench\u002Fblob\u002Fmain\u002Fskills\u002Fhuman_authored\u002Ftravel-planning\u002Fbundled-dataset-search-tool\u002FSKILL.md",[],[108,109,110,111,112,113,114,89,115,116,90,117,95,118,87],"search","tool","dataset","bundled dataset search tool","restaurants","Tools","up","look","flights","you","database",{"skillNo":120,"name":121,"nameZh":6,"description":122,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":123,"categories":124,"keywords":125,"publishedAt":31},"01M6KM465BB9PQ0B548HQSVAWZ","glm-output","Output-processing guidance for GLM tasks. Especially useful after glm-basics and glm-calibration when you need verifier-matching metrics from output.nc and a final \u002Froot\u002Fmetrics.json.","https:\u002F\u002Fgithub.com\u002Fcxcscmu\u002FSkillLearnBench\u002Fblob\u002Fmain\u002Fskills\u002Fhuman_authored\u002Ftemperature-simulation\u002Fglm-output\u002FSKILL.md",[],[126,127,128,95,129,130,131,132,133,134,135,136,117,137,138],"glm output","output","glm","tasks","metrics","json","basics","guidance","matching","verifier","processing","root","calibration",{"skillNo":140,"name":141,"nameZh":6,"description":142,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":143,"categories":144,"keywords":146,"publishedAt":31},"01M6KM40KY3QWDW5W97S39R2BC","glm-calibration","Calibration guidance for GLM tasks. Often most effective after glm-basics has clarified the setup; glm-output is the companion skill for exact final metric computation.","https:\u002F\u002Fgithub.com\u002Fcxcscmu\u002FSkillLearnBench\u002Fblob\u002Fmain\u002Fskills\u002Fhuman_authored\u002Ftemperature-simulation\u002Fglm-calibration\u002FSKILL.md",[145],{"categoryNo":83,"categoryName":84,"taxonomyType":68,"taxonomyTypeDesc":69},[147,138,128,127,133,132,129,148,27,95,149],"glm calibration","setup","metric",{"skillNo":151,"name":152,"nameZh":6,"description":153,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":154,"categories":155,"keywords":156,"publishedAt":31},"01M6KM3VHHVSGMGHJQB3PPT6YG","glm-basics","A good starting point for GLM calibration tasks. Use to inspect glm3.nml, confirm how GLM runs, and identify the relevant files before moving on to calibration and output evaluation.","https:\u002F\u002Fgithub.com\u002Fcxcscmu\u002FSkillLearnBench\u002Fblob\u002Fmain\u002Fskills\u002Fhuman_authored\u002Ftemperature-simulation\u002Fglm-basics\u002FSKILL.md",[],[157,128,132,158,147,138,95,127,159,160,161,162,163,164,129],"glm basics","inspect","relevant","files","good","use","how","Evaluation"]