@k2works/claude-code-booster 3.0.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/assets/docs/article/functional-desgin-ppp/all/01-immutability-and-data-transformation.md +475 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/02-function-composition.md +519 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/03-polymorphism.md +537 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/04-data-validation.md +300 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/05-property-based-testing.md +320 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/06-tdd-and-functional.md +498 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/07-composite-pattern.md +298 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/08-decorator-pattern.md +291 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/09-adapter-pattern.md +336 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/10-strategy-pattern.md +303 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/11-command-pattern.md +286 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/12-visitor-pattern.md +322 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/13-abstract-factory-pattern.md +319 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/14-abstract-server-pattern.md +365 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/15-gossiping-bus-drivers.md +156 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/16-payroll-system.md +178 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/17-video-rental-system.md +312 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/18-concurrency-system.md +287 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/19-wa-tor-simulation.md +286 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/20-pattern-interactions.md +274 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/21-best-practices.md +294 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/22-oo-to-fp-migration.md +337 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/index.md +388 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/01-immutability-and-data-transformation.md +271 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/02-function-composition.md +380 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/03-polymorphism.md +384 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/04-clojure-spec.md +350 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/05-property-based-testing.md +352 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/06-tdd-in-functional.md +383 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/07-composite-pattern.md +529 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/08-decorator-pattern.md +395 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/09-adapter-pattern.md +399 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/10-strategy-pattern.md +485 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/11-command-pattern.md +566 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/12-visitor-pattern.md +567 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/13-abstract-factory-pattern.md +475 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/14-abstract-server-pattern.md +462 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/15-gossiping-bus-drivers.md +323 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/16-payroll-system.md +401 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/17-video-rental-system.md +450 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/18-concurrency-system.md +475 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/19-wator-simulation.md +739 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/20-pattern-interactions.md +562 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/21-best-practices.md +506 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/22-oo-to-fp-migration.md +526 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/index.md +197 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/01-immutability-and-data-transformation.md +381 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/02-function-composition.md +374 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/03-polymorphism.md +375 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/04-data-validation.md +195 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/05-property-based-testing.md +268 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/06-tdd-and-fp.md +294 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/07-effects-and-pure-functions.md +164 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/08-error-handling-strategies.md +168 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/09-io-and-external-systems.md +254 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/10-concurrency-patterns.md +269 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/11-command-pattern.md +148 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/12-visitor-pattern.md +176 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/13-abstract-factory-pattern.md +604 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/14-abstract-server-pattern.md +729 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/15-gossiping-bus-drivers.md +291 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/16-payroll-system.md +420 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/17-video-rental-system.md +319 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/18-concurrency-system.md +466 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/19-wator-simulation.md +523 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/20-pattern-interactions.md +287 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/21-best-practices.md +340 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/22-oo-to-fp-migration.md +395 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/index.md +204 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/01-immutability-and-data-transformation.md +382 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/02-function-composition.md +452 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/03-polymorphism.md +495 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/04-data-validation.md +416 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/05-property-based-testing.md +382 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/06-tdd-functional.md +687 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/07-composite-pattern.md +442 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/08-decorator-pattern.md +479 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/09-adapter-pattern.md +479 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/10-strategy-pattern.md +427 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/11-command-pattern.md +428 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/12-visitor-pattern.md +339 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/13-abstract-factory-pattern.md +309 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/14-abstract-server-pattern.md +596 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/15-gossiping-bus-drivers.md +353 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/16-payroll-system.md +350 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/17-video-rental-system.md +412 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/18-concurrency-system.md +367 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/19-wator-simulation.md +401 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/20-pattern-interactions.md +291 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/21-best-practices.md +320 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/22-oo-to-fp-migration.md +322 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/index.md +230 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/01-immutability-and-data-transformation.md +298 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/02-function-composition.md +304 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/03-polymorphism.md +362 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/04-data-validation.md +257 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/05-property-based-testing.md +254 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/06-tdd-functional.md +283 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/07-composite-pattern.md +395 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/08-decorator-pattern.md +319 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/09-adapter-pattern.md +382 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/10-strategy-pattern.md +287 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/11-command-pattern.md +303 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/12-visitor-pattern.md +326 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/13-abstract-factory-pattern.md +332 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/14-abstract-server-pattern.md +379 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/15-gossiping-bus-drivers.md +175 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/16-payroll-system.md +219 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/17-video-rental-system.md +244 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/18-concurrency-system.md +363 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/19-wator-simulation.md +438 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/20-pattern-interactions.md +323 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/21-best-practices.md +403 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/22-oo-to-fp-migration.md +469 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/index.md +174 -0
- package/lib/assets/docs/article/functional-desgin-ppp/index.md +90 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/01-immutability-and-data-transformation.md +448 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/02-function-composition.md +463 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/03-polymorphism.md +425 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/04-data-validation.md +273 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/05-property-based-testing.md +247 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/06-tdd-and-functional.md +841 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/07-composite-pattern.md +384 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/08-decorator-pattern.md +383 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/09-adapter-pattern.md +339 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/10-strategy-pattern.md +331 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/11-command-pattern.md +356 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/12-visitor-pattern.md +379 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/13-abstract-factory-pattern.md +361 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/14-abstract-server-pattern.md +392 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/15-gossiping-bus-drivers.md +300 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/16-payroll-system.md +297 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/17-video-rental-system.md +304 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/18-concurrency-system.md +315 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/19-wator-simulation.md +311 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/20-pattern-interactions.md +304 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/21-best-practices.md +336 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/22-oo-to-fp-migration.md +349 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/index.md +199 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/01-immutability-and-data-transformation.md +326 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/02-function-composition.md +348 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/03-polymorphism.md +357 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/04-data-validation.md +364 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/05-property-based-testing.md +515 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/06-tdd-functional.md +557 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/07-composite-pattern.md +363 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/08-decorator-pattern.md +327 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/09-adapter-pattern.md +517 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/10-strategy-pattern.md +441 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/11-command-pattern.md +407 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/12-visitor-pattern.md +379 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/13-abstract-factory-pattern.md +398 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/14-abstract-server-pattern.md +476 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/15-gossiping-bus-drivers.md +389 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/16-payroll-system.md +342 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/17-video-rental-system.md +324 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/18-concurrency-system.md +730 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/19-wator-simulation.md +624 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/20-pattern-interactions.md +512 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/21-best-practices.md +427 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/22-oo-to-fp-migration.md +682 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/index.md +199 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/01-todo-list-and-first-test.md +166 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/02-fake-it-and-triangulation.md +162 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/03-obvious-implementation-and-refactoring.md +135 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/04-version-control-and-conventional-commits.md +88 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/05-package-management-and-static-analysis.md +299 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/06-task-runner-and-ci-cd.md +241 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/07-protocols-and-records.md +131 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/08-multimethods-and-design-patterns.md +130 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/09-namespaces-and-module-design.md +127 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/10-higher-order-functions-and-composition.md +114 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/11-persistent-data-and-pipeline.md +138 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/12-error-handling-and-spec.md +161 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/index.md +65 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter01.md +232 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter02.md +244 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter03.md +202 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter04.md +92 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter05.md +256 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter06.md +195 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter07.md +214 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter08.md +249 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter09.md +174 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter10.md +166 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter11.md +192 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter12.md +211 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/index.md +83 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/01-todo-list-and-first-test.md +87 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/02-fake-it-and-triangulation.md +95 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/03-obvious-implementation-and-refactoring.md +109 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/04-version-control-and-conventional-commits.md +96 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/05-package-management-and-static-analysis.md +88 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/06-task-runner-and-ci-cd.md +71 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/07-structs-and-protocols.md +110 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/08-pattern-matching-and-guards.md +108 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/09-module-design-and-behaviours.md +104 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/10-higher-order-functions-and-pipeline.md +178 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/11-stream-and-lazy-evaluation.md +142 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/12-error-handling-and-with.md +145 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/index.md +35 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter01.md +202 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter02.md +246 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter03.md +218 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter04.md +179 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter05.md +267 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter06.md +190 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter07.md +161 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter08.md +175 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter09.md +222 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter10.md +189 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter11.md +212 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter12.md +215 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/index.md +71 -0
- package/lib/assets/docs/article/getting-start-tdd/go/01-todo-list-and-first-test.md +213 -0
- package/lib/assets/docs/article/getting-start-tdd/go/02-fake-it-and-triangulation.md +302 -0
- package/lib/assets/docs/article/getting-start-tdd/go/03-obvious-implementation-and-refactoring.md +339 -0
- package/lib/assets/docs/article/getting-start-tdd/go/04-version-control-and-conventional-commits.md +112 -0
- package/lib/assets/docs/article/getting-start-tdd/go/05-package-management-and-static-analysis.md +272 -0
- package/lib/assets/docs/article/getting-start-tdd/go/06-task-runner-and-ci-cd.md +233 -0
- package/lib/assets/docs/article/getting-start-tdd/go/07-encapsulation-and-polymorphism.md +394 -0
- package/lib/assets/docs/article/getting-start-tdd/go/08-design-patterns.md +422 -0
- package/lib/assets/docs/article/getting-start-tdd/go/09-solid-principles-and-module-design.md +400 -0
- package/lib/assets/docs/article/getting-start-tdd/go/10-higher-order-functions-and-composition.md +226 -0
- package/lib/assets/docs/article/getting-start-tdd/go/11-immutable-data-and-pipeline.md +296 -0
- package/lib/assets/docs/article/getting-start-tdd/go/12-error-handling-and-type-safety.md +411 -0
- package/lib/assets/docs/article/getting-start-tdd/go/index.md +83 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/01-todo-list-and-first-test.md +279 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/02-fake-it-and-triangulation.md +337 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/03-obvious-implementation-and-refactoring.md +257 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/04-version-control-and-conventional-commits.md +182 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/05-package-management-and-static-analysis.md +313 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/06-task-runner-and-ci-cd.md +309 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/07-algebraic-data-types-and-type-classes.md +412 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/08-pattern-matching-and-guards.md +390 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/09-module-design-and-smart-constructors.md +461 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/10-higher-order-functions-and-currying.md +434 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/11-function-composition-and-point-free.md +392 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/12-monad-and-error-handling.md +631 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/index.md +49 -0
- package/lib/assets/docs/article/getting-start-tdd/index.md +93 -0
- package/lib/assets/docs/article/getting-start-tdd/integration/01-language-overview.md +375 -0
- package/lib/assets/docs/article/getting-start-tdd/integration/02-test-framework-comparison.md +349 -0
- package/lib/assets/docs/article/getting-start-tdd/integration/03-tdd-pattern-comparison.md +445 -0
- package/lib/assets/docs/article/getting-start-tdd/integration/04-type-system-comparison.md +405 -0
- package/lib/assets/docs/article/getting-start-tdd/integration/05-dev-environment-comparison.md +330 -0
- package/lib/assets/docs/article/getting-start-tdd/integration/06-learning-roadmap.md +274 -0
- package/lib/assets/docs/article/getting-start-tdd/integration/index.md +69 -0
- package/lib/assets/docs/article/getting-start-tdd/java/01-todo-list-and-first-test.md +234 -0
- package/lib/assets/docs/article/getting-start-tdd/java/02-fake-it-and-triangulation.md +261 -0
- package/lib/assets/docs/article/getting-start-tdd/java/03-obvious-implementation-and-refactoring.md +185 -0
- package/lib/assets/docs/article/getting-start-tdd/java/04-version-control-and-conventional-commits.md +115 -0
- package/lib/assets/docs/article/getting-start-tdd/java/05-package-management-and-static-analysis.md +382 -0
- package/lib/assets/docs/article/getting-start-tdd/java/06-task-runner-and-ci-cd.md +272 -0
- package/lib/assets/docs/article/getting-start-tdd/java/07-encapsulation-and-polymorphism.md +626 -0
- package/lib/assets/docs/article/getting-start-tdd/java/08-design-patterns.md +393 -0
- package/lib/assets/docs/article/getting-start-tdd/java/09-solid-principles-and-module-design.md +310 -0
- package/lib/assets/docs/article/getting-start-tdd/java/10-higher-order-functions-and-composition.md +188 -0
- package/lib/assets/docs/article/getting-start-tdd/java/11-immutable-data-and-pipeline.md +167 -0
- package/lib/assets/docs/article/getting-start-tdd/java/12-error-handling-and-type-safety.md +205 -0
- package/lib/assets/docs/article/getting-start-tdd/java/index.md +61 -0
- package/lib/assets/docs/article/getting-start-tdd/node/01-todo-list-and-first-test.md +244 -0
- package/lib/assets/docs/article/getting-start-tdd/node/02-fake-it-and-triangulation.md +262 -0
- package/lib/assets/docs/article/getting-start-tdd/node/03-obvious-implementation-and-refactoring.md +169 -0
- package/lib/assets/docs/article/getting-start-tdd/node/04-version-control-and-conventional-commits.md +112 -0
- package/lib/assets/docs/article/getting-start-tdd/node/05-package-management-and-static-analysis.md +314 -0
- package/lib/assets/docs/article/getting-start-tdd/node/06-task-runner-and-ci-cd.md +235 -0
- package/lib/assets/docs/article/getting-start-tdd/node/07-encapsulation-and-polymorphism.md +327 -0
- package/lib/assets/docs/article/getting-start-tdd/node/08-design-patterns.md +322 -0
- package/lib/assets/docs/article/getting-start-tdd/node/09-solid-principles-and-module-design.md +285 -0
- package/lib/assets/docs/article/getting-start-tdd/node/10-higher-order-functions-and-composition.md +199 -0
- package/lib/assets/docs/article/getting-start-tdd/node/11-immutable-data-and-pipeline.md +207 -0
- package/lib/assets/docs/article/getting-start-tdd/node/12-error-handling-and-type-safety.md +295 -0
- package/lib/assets/docs/article/getting-start-tdd/node/index.md +56 -0
- package/lib/assets/docs/article/getting-start-tdd/php/01-todo-list-and-first-test.md +259 -0
- package/lib/assets/docs/article/getting-start-tdd/php/02-fake-it-and-triangulation.md +200 -0
- package/lib/assets/docs/article/getting-start-tdd/php/03-obvious-implementation-and-refactoring.md +248 -0
- package/lib/assets/docs/article/getting-start-tdd/php/04-version-control-and-conventional-commits.md +141 -0
- package/lib/assets/docs/article/getting-start-tdd/php/05-package-management-and-static-analysis.md +410 -0
- package/lib/assets/docs/article/getting-start-tdd/php/06-task-runner-and-ci-cd.md +321 -0
- package/lib/assets/docs/article/getting-start-tdd/php/07-encapsulation-and-polymorphism.md +372 -0
- package/lib/assets/docs/article/getting-start-tdd/php/08-design-patterns.md +453 -0
- package/lib/assets/docs/article/getting-start-tdd/php/09-solid-principles-and-module-design.md +460 -0
- package/lib/assets/docs/article/getting-start-tdd/php/10-higher-order-functions-and-composition.md +182 -0
- package/lib/assets/docs/article/getting-start-tdd/php/11-immutable-data-and-pipeline.md +266 -0
- package/lib/assets/docs/article/getting-start-tdd/php/12-error-handling-and-type-safety.md +308 -0
- package/lib/assets/docs/article/getting-start-tdd/php/index.md +84 -0
- package/lib/assets/docs/article/getting-start-tdd/python/01-todo-list-and-first-test.md +201 -0
- package/lib/assets/docs/article/getting-start-tdd/python/02-fake-it-and-triangulation.md +247 -0
- package/lib/assets/docs/article/getting-start-tdd/python/03-obvious-implementation-and-refactoring.md +199 -0
- package/lib/assets/docs/article/getting-start-tdd/python/04-version-control-and-conventional-commits.md +87 -0
- package/lib/assets/docs/article/getting-start-tdd/python/05-package-management-and-static-analysis.md +274 -0
- package/lib/assets/docs/article/getting-start-tdd/python/06-task-runner-and-ci-cd.md +190 -0
- package/lib/assets/docs/article/getting-start-tdd/python/07-encapsulation-and-polymorphism.md +208 -0
- package/lib/assets/docs/article/getting-start-tdd/python/08-design-patterns.md +172 -0
- package/lib/assets/docs/article/getting-start-tdd/python/09-solid-principles-and-module-design.md +130 -0
- package/lib/assets/docs/article/getting-start-tdd/python/10-higher-order-functions-and-composition.md +122 -0
- package/lib/assets/docs/article/getting-start-tdd/python/11-immutable-data-and-pipeline.md +116 -0
- package/lib/assets/docs/article/getting-start-tdd/python/12-error-handling-and-type-safety.md +126 -0
- package/lib/assets/docs/article/getting-start-tdd/python/index.md +55 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/01-todo-list-and-first-test.md +231 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/02-fake-it-and-triangulation.md +238 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/03-obvious-implementation-and-refactoring.md +228 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/04-version-control-and-conventional-commits.md +112 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/05-package-management-and-static-analysis.md +287 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/06-task-runner-and-ci-cd.md +248 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/07-encapsulation-and-polymorphism.md +279 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/08-design-patterns.md +329 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/09-solid-principles-and-module-design.md +196 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/10-higher-order-functions-and-composition.md +175 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/11-immutable-data-and-pipeline.md +233 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/12-error-handling-and-type-safety.md +398 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/index.md +83 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/01-todo-list-and-first-test.md +211 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/02-fake-it-and-triangulation.md +264 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/03-obvious-implementation-and-refactoring.md +233 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/04-version-control-and-conventional-commits.md +92 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/05-package-management-and-static-analysis.md +212 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/06-task-runner-and-ci-cd.md +164 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/07-encapsulation-and-polymorphism.md +142 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/08-design-patterns.md +145 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/09-solid-principles-and-module-design.md +110 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/10-higher-order-functions-and-composition.md +94 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/11-immutable-data-and-pipeline.md +105 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/12-error-handling-and-type-safety.md +112 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/index.md +83 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/01-todo-list-and-first-test.md +111 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/02-fake-it-and-triangulation.md +107 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/03-obvious-implementation-and-refactoring.md +99 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/04-version-control-and-conventional-commits.md +123 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/05-package-management-and-static-analysis.md +196 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/06-task-runner-and-ci-cd.md +186 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/07-case-classes-and-traits.md +139 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/08-pattern-matching-and-sealed-traits.md +106 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/09-packages-and-module-design.md +75 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/10-higher-order-functions-and-composition.md +104 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/11-collections-and-lazy-evaluation.md +94 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/12-error-handling-and-type-safety.md +92 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/index.md +65 -0
- package/lib/assets/docs/article/grokking-concurrency/all/index.md +404 -0
- package/lib/assets/docs/article/grokking-concurrency/all/part-1-ch02-sequential.md +554 -0
- package/lib/assets/docs/article/grokking-concurrency/all/part-2-ch04-05-threads.md +469 -0
- package/lib/assets/docs/article/grokking-concurrency/all/part-3-ch06-multitasking.md +520 -0
- package/lib/assets/docs/article/grokking-concurrency/all/part-4-ch07-parallel-patterns.md +420 -0
- package/lib/assets/docs/article/grokking-concurrency/all/part-5-ch08-09-synchronization.md +510 -0
- package/lib/assets/docs/article/grokking-concurrency/all/part-6-ch10-11-nonblocking-io.md +435 -0
- package/lib/assets/docs/article/grokking-concurrency/all/part-7-ch12-async.md +465 -0
- package/lib/assets/docs/article/grokking-concurrency/all/part-8-ch13-mapreduce.md +377 -0
- package/lib/assets/docs/article/grokking-concurrency/clojure/index.md +116 -0
- package/lib/assets/docs/article/grokking-concurrency/clojure/part-1.md +108 -0
- package/lib/assets/docs/article/grokking-concurrency/clojure/part-2.md +101 -0
- package/lib/assets/docs/article/grokking-concurrency/clojure/part-3.md +122 -0
- package/lib/assets/docs/article/grokking-concurrency/clojure/part-4.md +123 -0
- package/lib/assets/docs/article/grokking-concurrency/clojure/part-5.md +118 -0
- package/lib/assets/docs/article/grokking-concurrency/clojure/part-6.md +89 -0
- package/lib/assets/docs/article/grokking-concurrency/clojure/part-7.md +100 -0
- package/lib/assets/docs/article/grokking-concurrency/clojure/part-8.md +120 -0
- package/lib/assets/docs/article/grokking-concurrency/csharp/index.md +101 -0
- package/lib/assets/docs/article/grokking-concurrency/csharp/part-1.md +97 -0
- package/lib/assets/docs/article/grokking-concurrency/csharp/part-2.md +123 -0
- package/lib/assets/docs/article/grokking-concurrency/csharp/part-3.md +101 -0
- package/lib/assets/docs/article/grokking-concurrency/csharp/part-4.md +112 -0
- package/lib/assets/docs/article/grokking-concurrency/csharp/part-5.md +99 -0
- package/lib/assets/docs/article/grokking-concurrency/csharp/part-6.md +61 -0
- package/lib/assets/docs/article/grokking-concurrency/csharp/part-7.md +84 -0
- package/lib/assets/docs/article/grokking-concurrency/csharp/part-8.md +92 -0
- package/lib/assets/docs/article/grokking-concurrency/fsharp/index.md +65 -0
- package/lib/assets/docs/article/grokking-concurrency/fsharp/part-1.md +80 -0
- package/lib/assets/docs/article/grokking-concurrency/fsharp/part-2.md +103 -0
- package/lib/assets/docs/article/grokking-concurrency/fsharp/part-3.md +94 -0
- package/lib/assets/docs/article/grokking-concurrency/fsharp/part-4.md +110 -0
- package/lib/assets/docs/article/grokking-concurrency/fsharp/part-5.md +104 -0
- package/lib/assets/docs/article/grokking-concurrency/fsharp/part-6.md +93 -0
- package/lib/assets/docs/article/grokking-concurrency/fsharp/part-7.md +121 -0
- package/lib/assets/docs/article/grokking-concurrency/fsharp/part-8.md +107 -0
- package/lib/assets/docs/article/grokking-concurrency/haskell/index.md +248 -0
- package/lib/assets/docs/article/grokking-concurrency/haskell/part-1.md +96 -0
- package/lib/assets/docs/article/grokking-concurrency/haskell/part-2.md +96 -0
- package/lib/assets/docs/article/grokking-concurrency/haskell/part-3.md +91 -0
- package/lib/assets/docs/article/grokking-concurrency/haskell/part-4.md +106 -0
- package/lib/assets/docs/article/grokking-concurrency/haskell/part-5.md +99 -0
- package/lib/assets/docs/article/grokking-concurrency/haskell/part-6.md +95 -0
- package/lib/assets/docs/article/grokking-concurrency/haskell/part-7.md +111 -0
- package/lib/assets/docs/article/grokking-concurrency/haskell/part-8.md +118 -0
- package/lib/assets/docs/article/grokking-concurrency/index.md +66 -0
- package/lib/assets/docs/article/grokking-concurrency/java/index.md +102 -0
- package/lib/assets/docs/article/grokking-concurrency/java/part-1.md +308 -0
- package/lib/assets/docs/article/grokking-concurrency/java/part-2.md +334 -0
- package/lib/assets/docs/article/grokking-concurrency/java/part-3.md +221 -0
- package/lib/assets/docs/article/grokking-concurrency/java/part-4.md +213 -0
- package/lib/assets/docs/article/grokking-concurrency/java/part-5.md +112 -0
- package/lib/assets/docs/article/grokking-concurrency/java/part-6.md +69 -0
- package/lib/assets/docs/article/grokking-concurrency/java/part-7.md +101 -0
- package/lib/assets/docs/article/grokking-concurrency/java/part-8.md +101 -0
- package/lib/assets/docs/article/grokking-concurrency/python/index.md +313 -0
- package/lib/assets/docs/article/grokking-concurrency/python/part-1.md +239 -0
- package/lib/assets/docs/article/grokking-concurrency/python/part-2.md +418 -0
- package/lib/assets/docs/article/grokking-concurrency/python/part-3.md +227 -0
- package/lib/assets/docs/article/grokking-concurrency/python/part-4.md +299 -0
- package/lib/assets/docs/article/grokking-concurrency/python/part-5.md +315 -0
- package/lib/assets/docs/article/grokking-concurrency/python/part-6.md +297 -0
- package/lib/assets/docs/article/grokking-concurrency/python/part-7.md +314 -0
- package/lib/assets/docs/article/grokking-concurrency/python/part-8.md +360 -0
- package/lib/assets/docs/article/grokking-concurrency/rust/index.md +270 -0
- package/lib/assets/docs/article/grokking-concurrency/rust/part-1.md +108 -0
- package/lib/assets/docs/article/grokking-concurrency/rust/part-2.md +120 -0
- package/lib/assets/docs/article/grokking-concurrency/rust/part-3.md +126 -0
- package/lib/assets/docs/article/grokking-concurrency/rust/part-4.md +175 -0
- package/lib/assets/docs/article/grokking-concurrency/rust/part-5.md +158 -0
- package/lib/assets/docs/article/grokking-concurrency/rust/part-6.md +94 -0
- package/lib/assets/docs/article/grokking-concurrency/rust/part-7.md +133 -0
- package/lib/assets/docs/article/grokking-concurrency/rust/part-8.md +155 -0
- package/lib/assets/docs/article/grokking-concurrency/scala/index.md +69 -0
- package/lib/assets/docs/article/grokking-concurrency/scala/part-1.md +78 -0
- package/lib/assets/docs/article/grokking-concurrency/scala/part-2.md +112 -0
- package/lib/assets/docs/article/grokking-concurrency/scala/part-3.md +93 -0
- package/lib/assets/docs/article/grokking-concurrency/scala/part-4.md +110 -0
- package/lib/assets/docs/article/grokking-concurrency/scala/part-5.md +119 -0
- package/lib/assets/docs/article/grokking-concurrency/scala/part-6.md +83 -0
- package/lib/assets/docs/article/grokking-concurrency/scala/part-7.md +131 -0
- package/lib/assets/docs/article/grokking-concurrency/scala/part-8.md +129 -0
- package/lib/assets/docs/article/grokkingfp/all/index.md +368 -0
- package/lib/assets/docs/article/grokkingfp/all/part-1-ch01-fp-introduction.md +530 -0
- package/lib/assets/docs/article/grokkingfp/all/part-1-ch02-pure-functions.md +923 -0
- package/lib/assets/docs/article/grokkingfp/all/part-2-ch03-immutable-data.md +1122 -0
- package/lib/assets/docs/article/grokkingfp/all/part-2-ch04-higher-order-functions.md +1104 -0
- package/lib/assets/docs/article/grokkingfp/all/part-2-ch05-flatmap.md +1026 -0
- package/lib/assets/docs/article/grokkingfp/all/part-3-ch06-option.md +777 -0
- package/lib/assets/docs/article/grokkingfp/all/part-3-ch07-either-adt.md +871 -0
- package/lib/assets/docs/article/grokkingfp/all/part-4-ch08-io-monad.md +972 -0
- package/lib/assets/docs/article/grokkingfp/all/part-4-ch09-streams.md +926 -0
- package/lib/assets/docs/article/grokkingfp/all/part-5-ch10-concurrency.md +870 -0
- package/lib/assets/docs/article/grokkingfp/all/part-6-ch11-application.md +715 -0
- package/lib/assets/docs/article/grokkingfp/all/part-6-ch12-testing.md +626 -0
- package/lib/assets/docs/article/grokkingfp/all/writing-plan.md +696 -0
- package/lib/assets/docs/article/grokkingfp/clojure/index.md +276 -0
- package/lib/assets/docs/article/grokkingfp/clojure/part-1.md +667 -0
- package/lib/assets/docs/article/grokkingfp/clojure/part-2.md +643 -0
- package/lib/assets/docs/article/grokkingfp/clojure/part-3.md +620 -0
- package/lib/assets/docs/article/grokkingfp/clojure/part-4.md +697 -0
- package/lib/assets/docs/article/grokkingfp/clojure/part-5.md +751 -0
- package/lib/assets/docs/article/grokkingfp/clojure/part-6.md +721 -0
- package/lib/assets/docs/article/grokkingfp/csharp/index.md +246 -0
- package/lib/assets/docs/article/grokkingfp/csharp/part-1.md +811 -0
- package/lib/assets/docs/article/grokkingfp/csharp/part-2.md +971 -0
- package/lib/assets/docs/article/grokkingfp/csharp/part-3.md +981 -0
- package/lib/assets/docs/article/grokkingfp/csharp/part-4.md +949 -0
- package/lib/assets/docs/article/grokkingfp/csharp/part-5.md +947 -0
- package/lib/assets/docs/article/grokkingfp/csharp/part-6.md +739 -0
- package/lib/assets/docs/article/grokkingfp/elixir/index.md +203 -0
- package/lib/assets/docs/article/grokkingfp/elixir/part-1.md +710 -0
- package/lib/assets/docs/article/grokkingfp/elixir/part-2.md +838 -0
- package/lib/assets/docs/article/grokkingfp/elixir/part-3.md +985 -0
- package/lib/assets/docs/article/grokkingfp/elixir/part-4.md +974 -0
- package/lib/assets/docs/article/grokkingfp/elixir/part-5.md +1284 -0
- package/lib/assets/docs/article/grokkingfp/elixir/part-6.md +1047 -0
- package/lib/assets/docs/article/grokkingfp/fsharp/index.md +210 -0
- package/lib/assets/docs/article/grokkingfp/fsharp/part-1.md +714 -0
- package/lib/assets/docs/article/grokkingfp/fsharp/part-2.md +961 -0
- package/lib/assets/docs/article/grokkingfp/fsharp/part-3.md +972 -0
- package/lib/assets/docs/article/grokkingfp/fsharp/part-4.md +832 -0
- package/lib/assets/docs/article/grokkingfp/fsharp/part-5.md +911 -0
- package/lib/assets/docs/article/grokkingfp/fsharp/part-6.md +920 -0
- package/lib/assets/docs/article/grokkingfp/haskell/index.md +234 -0
- package/lib/assets/docs/article/grokkingfp/haskell/part-1.md +591 -0
- package/lib/assets/docs/article/grokkingfp/haskell/part-2.md +866 -0
- package/lib/assets/docs/article/grokkingfp/haskell/part-3.md +915 -0
- package/lib/assets/docs/article/grokkingfp/haskell/part-4.md +876 -0
- package/lib/assets/docs/article/grokkingfp/haskell/part-5.md +845 -0
- package/lib/assets/docs/article/grokkingfp/haskell/part-6.md +842 -0
- package/lib/assets/docs/article/grokkingfp/index.md +143 -0
- package/lib/assets/docs/article/grokkingfp/java/index.md +211 -0
- package/lib/assets/docs/article/grokkingfp/java/part-1.md +646 -0
- package/lib/assets/docs/article/grokkingfp/java/part-2.md +667 -0
- package/lib/assets/docs/article/grokkingfp/java/part-3.md +672 -0
- package/lib/assets/docs/article/grokkingfp/java/part-4.md +771 -0
- package/lib/assets/docs/article/grokkingfp/java/part-5.md +959 -0
- package/lib/assets/docs/article/grokkingfp/java/part-6.md +1324 -0
- package/lib/assets/docs/article/grokkingfp/python/index.md +258 -0
- package/lib/assets/docs/article/grokkingfp/python/part-1.md +437 -0
- package/lib/assets/docs/article/grokkingfp/python/part-2.md +958 -0
- package/lib/assets/docs/article/grokkingfp/python/part-3.md +1004 -0
- package/lib/assets/docs/article/grokkingfp/python/part-4.md +765 -0
- package/lib/assets/docs/article/grokkingfp/python/part-5.md +747 -0
- package/lib/assets/docs/article/grokkingfp/python/part-6.md +861 -0
- package/lib/assets/docs/article/grokkingfp/ruby/index.md +330 -0
- package/lib/assets/docs/article/grokkingfp/ruby/part-1.md +753 -0
- package/lib/assets/docs/article/grokkingfp/ruby/part-2.md +938 -0
- package/lib/assets/docs/article/grokkingfp/ruby/part-3.md +946 -0
- package/lib/assets/docs/article/grokkingfp/ruby/part-4.md +921 -0
- package/lib/assets/docs/article/grokkingfp/ruby/part-5.md +908 -0
- package/lib/assets/docs/article/grokkingfp/ruby/part-6.md +1410 -0
- package/lib/assets/docs/article/grokkingfp/rust/index.md +242 -0
- package/lib/assets/docs/article/grokkingfp/rust/part-1.md +634 -0
- package/lib/assets/docs/article/grokkingfp/rust/part-2.md +1060 -0
- package/lib/assets/docs/article/grokkingfp/rust/part-3.md +994 -0
- package/lib/assets/docs/article/grokkingfp/rust/part-4.md +571 -0
- package/lib/assets/docs/article/grokkingfp/rust/part-5.md +705 -0
- package/lib/assets/docs/article/grokkingfp/rust/part-6.md +508 -0
- package/lib/assets/docs/article/grokkingfp/scala/index.md +171 -0
- package/lib/assets/docs/article/grokkingfp/scala/part-1.md +541 -0
- package/lib/assets/docs/article/grokkingfp/scala/part-2.md +946 -0
- package/lib/assets/docs/article/grokkingfp/scala/part-3.md +917 -0
- package/lib/assets/docs/article/grokkingfp/scala/part-4.md +742 -0
- package/lib/assets/docs/article/grokkingfp/scala/part-5.md +722 -0
- package/lib/assets/docs/article/grokkingfp/scala/part-6.md +865 -0
- package/lib/assets/docs/article/grokkingfp/typescript/index.md +273 -0
- package/lib/assets/docs/article/grokkingfp/typescript/part-1.md +559 -0
- package/lib/assets/docs/article/grokkingfp/typescript/part-2.md +1129 -0
- package/lib/assets/docs/article/grokkingfp/typescript/part-3.md +842 -0
- package/lib/assets/docs/article/grokkingfp/typescript/part-4.md +1085 -0
- package/lib/assets/docs/article/grokkingfp/typescript/part-5.md +717 -0
- package/lib/assets/docs/article/grokkingfp/typescript/part-6.md +980 -0
- package/lib/assets/docs/article/index.md +36 -0
- package/lib/assets/docs/design/index.md +39 -27
- package/lib/assets/docs/development/index.md +11 -1
- package/lib/assets/docs/index.md +33 -106
- package/lib/assets/docs/operation/index.md +16 -6
- package/lib/assets/docs/reference/index.md +5 -4
- package/lib/assets/docs/requirements/index.md +13 -6
- package/lib/assets/docs/strategy/index.md +11 -4
- package/lib/assets/docs/template/index.md +9 -5
- package/lib/assets/mkdocs.yml +29 -17
- package/package.json +1 -1
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# 第 7 章: ケースクラスとトレイトによるポリモーフィズム
|
|
2
|
+
|
|
3
|
+
## 7.1 はじめに
|
|
4
|
+
|
|
5
|
+
第 1 部〜第 2 部で TDD の基本サイクルと開発環境を整えました。ここからは FizzBuzz に追加仕様を導入し、オブジェクト指向設計を進めます。
|
|
6
|
+
|
|
7
|
+
今回の追加仕様は、FizzBuzz のタイプバリエーションです。
|
|
8
|
+
|
|
9
|
+
- Type01: 通常の FizzBuzz(3 の倍数で Fizz、5 の倍数で Buzz、15 の倍数で FizzBuzz)
|
|
10
|
+
- Type02: 数値のみ(常に数値文字列を返す)
|
|
11
|
+
- Type03: FizzBuzz のみ(15 の倍数のみ FizzBuzz、それ以外は数値文字列)
|
|
12
|
+
|
|
13
|
+
Scala では `case class` と `trait` を組み合わせることで、型安全なポリモーフィズムをシンプルに表現できます。
|
|
14
|
+
|
|
15
|
+
## 7.2 TODO リスト
|
|
16
|
+
|
|
17
|
+
既存 TODO に加えて、タイプバリエーションに関する TODO を整理します。
|
|
18
|
+
|
|
19
|
+
- [x] ~~1 を渡したら "1" を返す~~
|
|
20
|
+
- [x] ~~3 の倍数のときは "Fizz" を返す~~
|
|
21
|
+
- [x] ~~5 の倍数のときは "Buzz" を返す~~
|
|
22
|
+
- [x] ~~15 の倍数のときは "FizzBuzz" を返す~~
|
|
23
|
+
- [x] ~~1 から 100 までのリストを返す~~
|
|
24
|
+
- [ ] Type01 のルールを実装する
|
|
25
|
+
- [ ] Type02 のルールを実装する
|
|
26
|
+
- [ ] Type03 のルールを実装する
|
|
27
|
+
- [ ] 未定義タイプで例外を送出する
|
|
28
|
+
|
|
29
|
+
## 7.3 値オブジェクト(case class)
|
|
30
|
+
|
|
31
|
+
単一値の表現には `case class FizzBuzzValue` を使います。
|
|
32
|
+
|
|
33
|
+
```scala
|
|
34
|
+
case class FizzBuzzValue(number: Int, value: String):
|
|
35
|
+
require(number > 0, s"数値は正の整数でなければなりません: $number")
|
|
36
|
+
override def toString: String = value
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
`case class` の主な特徴は次のとおりです。
|
|
40
|
+
|
|
41
|
+
- 不変データを簡潔に定義できる
|
|
42
|
+
- `equals` / `hashCode` / `toString` が自動生成される
|
|
43
|
+
- パターンマッチに自然に対応できる
|
|
44
|
+
|
|
45
|
+
また、`require` により「正の整数であること」という事前条件をコンストラクタ境界で保証しています。
|
|
46
|
+
|
|
47
|
+
## 7.4 ファーストクラスコレクション
|
|
48
|
+
|
|
49
|
+
複数値の表現には `FizzBuzzList` を使います。
|
|
50
|
+
|
|
51
|
+
```scala
|
|
52
|
+
case class FizzBuzzList(values: List[FizzBuzzValue]):
|
|
53
|
+
require(values.nonEmpty, "リストは空であってはなりません")
|
|
54
|
+
def toStringList: List[String] = values.map(_.value)
|
|
55
|
+
def count: Int = values.length
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
`List[FizzBuzzValue]` を直接扱わず、`FizzBuzzList` にラップすることで、コレクション操作をドメインの語彙で表現できます。
|
|
59
|
+
|
|
60
|
+
実装ではコンパニオンオブジェクトに `create` を持たせ、生成ロジックを集約しています。
|
|
61
|
+
|
|
62
|
+
```scala
|
|
63
|
+
object FizzBuzzList:
|
|
64
|
+
def create(count: Int, fizzBuzzType: FizzBuzzType): FizzBuzzList =
|
|
65
|
+
val values = (1 to count).map { n =>
|
|
66
|
+
FizzBuzzValue(n, fizzBuzzType.generate(n))
|
|
67
|
+
}.toList
|
|
68
|
+
FizzBuzzList(values)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## 7.5 トレイトによるポリモーフィズム
|
|
72
|
+
|
|
73
|
+
FizzBuzz のタイプごとの差し替えポイントは `FizzBuzzType` で抽象化します。
|
|
74
|
+
|
|
75
|
+
```scala
|
|
76
|
+
sealed trait FizzBuzzType:
|
|
77
|
+
def generate(number: Int): String
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
実装は 3 つの `case object` です。
|
|
81
|
+
|
|
82
|
+
```scala
|
|
83
|
+
object FizzBuzzType:
|
|
84
|
+
case object Type01 extends FizzBuzzType:
|
|
85
|
+
def generate(number: Int): String =
|
|
86
|
+
number match
|
|
87
|
+
case n if n % 15 == 0 => "FizzBuzz"
|
|
88
|
+
case n if n % 3 == 0 => "Fizz"
|
|
89
|
+
case n if n % 5 == 0 => "Buzz"
|
|
90
|
+
case n => n.toString
|
|
91
|
+
|
|
92
|
+
case object Type02 extends FizzBuzzType:
|
|
93
|
+
def generate(number: Int): String = number.toString
|
|
94
|
+
|
|
95
|
+
case object Type03 extends FizzBuzzType:
|
|
96
|
+
def generate(number: Int): String =
|
|
97
|
+
number match
|
|
98
|
+
case n if n % 15 == 0 => "FizzBuzz"
|
|
99
|
+
case n => n.toString
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
`sealed` を付けることで実装候補を同一ファイルに閉じ込められ、コンパイラの網羅性チェックが効くようになります。
|
|
103
|
+
|
|
104
|
+
## 7.6 テスト
|
|
105
|
+
|
|
106
|
+
`TypeSpec` では各タイプとファクトリメソッドを検証しています。
|
|
107
|
+
|
|
108
|
+
```scala
|
|
109
|
+
class TypeSpec extends AnyFunSuite:
|
|
110
|
+
test("Type01: 3 の倍数で Fizz を返す") {
|
|
111
|
+
assert(FizzBuzzType.Type01.generate(3) === "Fizz")
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
test("Type02: 15 を渡すと 15 を返す") {
|
|
115
|
+
assert(FizzBuzzType.Type02.generate(15) === "15")
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
test("Type03: 15 の倍数で FizzBuzz を返す") {
|
|
119
|
+
assert(FizzBuzzType.Type03.generate(15) === "FizzBuzz")
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
test("create: 未定義のタイプで例外が発生する") {
|
|
123
|
+
assertThrows[IllegalArgumentException] {
|
|
124
|
+
FizzBuzzType.create(4)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
タイプごとの振る舞いを個別に固定することで、追加仕様時の回帰を防げます。
|
|
130
|
+
|
|
131
|
+
## 7.7 まとめ
|
|
132
|
+
|
|
133
|
+
この章では、`case class` と `trait` を使って FizzBuzz の型安全な設計を行いました。
|
|
134
|
+
|
|
135
|
+
- `FizzBuzzValue` で値を明示的に表現
|
|
136
|
+
- `FizzBuzzList` でコレクション操作をカプセル化
|
|
137
|
+
- `FizzBuzzType` のポリモーフィズムでタイプ差分を分離
|
|
138
|
+
|
|
139
|
+
次章では、`match` と `sealed trait` をさらに掘り下げ、Scala らしい分岐設計を整理します。
|
package/lib/assets/docs/article/getting-start-tdd/scala/08-pattern-matching-and-sealed-traits.md
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# 第 8 章: パターンマッチとシールドトレイト
|
|
2
|
+
|
|
3
|
+
## 8.1 はじめに
|
|
4
|
+
|
|
5
|
+
Scala の `match` は単なる `switch` の置き換えではなく、型と条件を統合して表現できる強力な構文です。`sealed trait` と組み合わせると、代数的データ型(ADT)として安全に分岐を記述できます。
|
|
6
|
+
|
|
7
|
+
この章では、FizzBuzz のタイプ生成と変換ロジックを題材に、パターンマッチの基本と網羅性チェックを確認します。
|
|
8
|
+
|
|
9
|
+
## 8.2 パターンマッチの基本
|
|
10
|
+
|
|
11
|
+
`match/case` の基本構文は次のとおりです。
|
|
12
|
+
|
|
13
|
+
```scala
|
|
14
|
+
def generate(number: Int): String =
|
|
15
|
+
number match
|
|
16
|
+
case n if n % 15 == 0 => "FizzBuzz"
|
|
17
|
+
case n if n % 3 == 0 => "Fizz"
|
|
18
|
+
case n if n % 5 == 0 => "Buzz"
|
|
19
|
+
case n => n.toString
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
重要な要素は 3 つです。
|
|
23
|
+
|
|
24
|
+
- `match/case` で分岐を宣言的に記述できる
|
|
25
|
+
- `case n if ...` のガード条件で複合条件を自然に表現できる
|
|
26
|
+
- `case _` や `case n` でワイルドカード/フォールバックを定義できる
|
|
27
|
+
|
|
28
|
+
## 8.3 シールドトレイトと網羅性
|
|
29
|
+
|
|
30
|
+
`sealed trait` は「この抽象型の実装は同一ファイル内に限定する」という制約を与えます。
|
|
31
|
+
|
|
32
|
+
```scala
|
|
33
|
+
sealed trait FizzBuzzType:
|
|
34
|
+
def generate(number: Int): String
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
この制約により、コンパイラは次を支援できます。
|
|
38
|
+
|
|
39
|
+
- 実装候補を把握し、網羅性を検証できる
|
|
40
|
+
- `match` で未処理ケースがあると警告できる
|
|
41
|
+
- 将来の型追加時に、分岐漏れを早期に検知できる
|
|
42
|
+
|
|
43
|
+
`sealed trait` は ADT を安全に扱うための土台です。
|
|
44
|
+
|
|
45
|
+
## 8.4 ファクトリメソッド
|
|
46
|
+
|
|
47
|
+
タイプ番号から `FizzBuzzType` を生成する実装です。
|
|
48
|
+
|
|
49
|
+
```scala
|
|
50
|
+
def create(typeNumber: Int): FizzBuzzType =
|
|
51
|
+
typeNumber match
|
|
52
|
+
case 1 => Type01
|
|
53
|
+
case 2 => Type02
|
|
54
|
+
case 3 => Type03
|
|
55
|
+
case _ => throw IllegalArgumentException(s"未定義のタイプ: $typeNumber")
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
生成責務を `FizzBuzzType.create` に集約することで、呼び出し側は型番号の解釈を意識せずに済みます。
|
|
59
|
+
|
|
60
|
+
## 8.5 Strategy パターンとの対応
|
|
61
|
+
|
|
62
|
+
OOP の Strategy パターンでは、アルゴリズムをインターフェースで抽象化し、実行時に具象実装を差し替えます。
|
|
63
|
+
|
|
64
|
+
FizzBuzz では次の対応になります。
|
|
65
|
+
|
|
66
|
+
- Strategy の抽象: `FizzBuzzType`(`sealed trait`)
|
|
67
|
+
- 具体 Strategy: `Type01` / `Type02` / `Type03`
|
|
68
|
+
- Strategy 選択: `FizzBuzzType.create(typeNumber)`
|
|
69
|
+
|
|
70
|
+
この構成により、呼び出し側の条件分岐を排除し、ポリモーフィズムで振る舞いを切り替えられます。
|
|
71
|
+
|
|
72
|
+
## 8.6 テスト
|
|
73
|
+
|
|
74
|
+
ファクトリメソッドは `TypeSpec` で次のように検証しています。
|
|
75
|
+
|
|
76
|
+
```scala
|
|
77
|
+
test("create: タイプ 1 を生成できる") {
|
|
78
|
+
assert(FizzBuzzType.create(1) === FizzBuzzType.Type01)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
test("create: タイプ 2 を生成できる") {
|
|
82
|
+
assert(FizzBuzzType.create(2) === FizzBuzzType.Type02)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
test("create: タイプ 3 を生成できる") {
|
|
86
|
+
assert(FizzBuzzType.create(3) === FizzBuzzType.Type03)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
test("create: 未定義のタイプで例外が発生する") {
|
|
90
|
+
assertThrows[IllegalArgumentException] {
|
|
91
|
+
FizzBuzzType.create(4)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
正常系と異常系を両方固定することで、生成ルールの変更に対して安全にリファクタリングできます。
|
|
97
|
+
|
|
98
|
+
## 8.7 まとめ
|
|
99
|
+
|
|
100
|
+
この章では、Scala のパターンマッチと `sealed trait` の組み合わせを確認しました。
|
|
101
|
+
|
|
102
|
+
- `match/case` とガード条件で分岐を明確化
|
|
103
|
+
- `sealed trait` で実装範囲を制約し、網羅性チェックを有効化
|
|
104
|
+
- `create` ファクトリで Strategy の切り替えを一元化
|
|
105
|
+
|
|
106
|
+
次章では、ここまで作成したドメインモデルをパッケージ単位で整理し、モジュール設計としてまとめます。
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# 第 9 章: パッケージとモジュール設計
|
|
2
|
+
|
|
3
|
+
## 9.1 はじめに
|
|
4
|
+
|
|
5
|
+
クラスが増えると、実装の正しさだけでなく「どこに何を書くか」が品質に直結します。この章では、FizzBuzz のコードを題材に、責務ごとに整理するモジュール設計を確認します。
|
|
6
|
+
|
|
7
|
+
## 9.2 パッケージ構成
|
|
8
|
+
|
|
9
|
+
現在の Scala 実装は次の構成です。
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
fizzbuzz/
|
|
13
|
+
├── FizzBuzz.scala (公開 API)
|
|
14
|
+
├── domain/
|
|
15
|
+
│ ├── Type.scala (ドメインタイプ)
|
|
16
|
+
│ └── Model.scala (値オブジェクト)
|
|
17
|
+
└── application/
|
|
18
|
+
└── Command.scala (コマンドパターン)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
`domain` と `application` を分離することで、ビジネスルールとユースケース実行を明確に切り分けています。
|
|
22
|
+
|
|
23
|
+
## 9.3 ドメイン層
|
|
24
|
+
|
|
25
|
+
ドメイン層は「FizzBuzz として何が正しいか」を表現する層です。
|
|
26
|
+
|
|
27
|
+
- `domain.Type`: 変換ルール(Type01/02/03)とファクトリメソッド
|
|
28
|
+
- `domain.Model`: 値オブジェクト `FizzBuzzValue` とファーストクラスコレクション `FizzBuzzList`
|
|
29
|
+
|
|
30
|
+
`require` による事前条件や `sealed trait` による型制約をドメイン側に置くことで、不正な状態の侵入を早期に防げます。
|
|
31
|
+
|
|
32
|
+
## 9.4 アプリケーション層
|
|
33
|
+
|
|
34
|
+
アプリケーション層はユースケースを実行する層です。
|
|
35
|
+
|
|
36
|
+
- `application.Command`: `FizzBuzzCommand` と具象コマンド
|
|
37
|
+
- `FizzBuzzValueCommand`: 単一値を返すユースケース
|
|
38
|
+
- `FizzBuzzListCommand`: 複数値を改行区切り文字列として返すユースケース
|
|
39
|
+
|
|
40
|
+
アプリケーション層は `domain` を利用しますが、`domain` は `application` に依存しません。この依存方向により、ビジネスルールを独立して保守できます。
|
|
41
|
+
|
|
42
|
+
## 9.5 Command パターン
|
|
43
|
+
|
|
44
|
+
`Command.scala` の中心となる実装です。
|
|
45
|
+
|
|
46
|
+
```scala
|
|
47
|
+
trait FizzBuzzCommand:
|
|
48
|
+
def execute(): String
|
|
49
|
+
|
|
50
|
+
class FizzBuzzValueCommand(number: Int, typeNumber: Int) extends FizzBuzzCommand:
|
|
51
|
+
def execute(): String =
|
|
52
|
+
val fizzBuzzType = FizzBuzzType.create(typeNumber)
|
|
53
|
+
val value = FizzBuzzValue(number, fizzBuzzType.generate(number))
|
|
54
|
+
value.toString
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
同じインターフェース(`execute`)で操作を抽象化し、呼び出し側はコマンドの差し替えだけで振る舞いを変更できます。
|
|
58
|
+
|
|
59
|
+
## 9.6 SOLID 原則との対応
|
|
60
|
+
|
|
61
|
+
この構成は SOLID 原則に次のように対応します。
|
|
62
|
+
|
|
63
|
+
- 単一責任: `Type.scala` は変換ルール、`Model.scala` は値表現、`Command.scala` は実行手順に責務分離
|
|
64
|
+
- 開放閉鎖: 新しいタイプは `FizzBuzzType` の実装追加で拡張しやすい
|
|
65
|
+
- 依存性逆転: `trait FizzBuzzCommand` と `trait FizzBuzzType` による抽象化で依存を安定化
|
|
66
|
+
|
|
67
|
+
## 9.7 まとめ
|
|
68
|
+
|
|
69
|
+
この章では、FizzBuzz 実装をパッケージ単位で整理し、モジュール設計の基本を確認しました。
|
|
70
|
+
|
|
71
|
+
- `domain` にビジネスルールを集約
|
|
72
|
+
- `application` にユースケース実行を集約
|
|
73
|
+
- `trait` を軸に依存関係をシンプルに保つ
|
|
74
|
+
|
|
75
|
+
第 3 部でオブジェクト指向設計の基盤が整ったので、次の第 4 部では関数型プログラミングの要素を取り入れて設計をさらに発展させます。
|
package/lib/assets/docs/article/getting-start-tdd/scala/10-higher-order-functions-and-composition.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# 第 10 章: 高階関数と関数合成
|
|
2
|
+
|
|
3
|
+
## 10.1 はじめに
|
|
4
|
+
|
|
5
|
+
第 3 部ではケースクラスやトレイトを使って OOP の基礎を整理しました。第 4 部では Scala の関数型プログラミング(FP)に焦点を当てます。
|
|
6
|
+
|
|
7
|
+
Scala では関数は第一級オブジェクトです。関数を変数に代入でき、引数として渡せて、戻り値として返せます。この性質により、柔軟で再利用しやすい実装が可能になります。
|
|
8
|
+
|
|
9
|
+
## 10.2 高階関数
|
|
10
|
+
|
|
11
|
+
高階関数は「関数を引数に取る、または関数を返す関数」です。`generateWith` は最小構成の例です。
|
|
12
|
+
|
|
13
|
+
```scala
|
|
14
|
+
def generateWith(rule: Int => String)(number: Int): String =
|
|
15
|
+
rule(number)
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
このメソッドは 2 つのパラメータリストを持つカリー化された形です。
|
|
19
|
+
|
|
20
|
+
- 第 1 パラメータリスト: `rule`(`Int => String`)
|
|
21
|
+
- 第 2 パラメータリスト: `number`(`Int`)
|
|
22
|
+
|
|
23
|
+
使い方の例です。
|
|
24
|
+
|
|
25
|
+
```scala
|
|
26
|
+
val customRule: Int => String = n => if n % 2 == 0 then "Even" else "Odd"
|
|
27
|
+
val generator = FizzBuzz.generateWith(customRule)
|
|
28
|
+
|
|
29
|
+
assert(generator(2) == "Even")
|
|
30
|
+
assert(generator(3) == "Odd")
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`val generator = FizzBuzz.generateWith(customRule)` は部分適用です。ルールだけ先に固定し、後から数値だけ渡せるようになります。
|
|
34
|
+
|
|
35
|
+
## 10.3 コレクション操作
|
|
36
|
+
|
|
37
|
+
Scala のコレクションは `map`、`filter`、`reduce` のような高階関数を標準で備えています。
|
|
38
|
+
|
|
39
|
+
- `map`: 各要素を変換する
|
|
40
|
+
- `filter`: 条件に一致する要素だけ残す
|
|
41
|
+
- `reduce`: 要素を 1 つの値に畳み込む
|
|
42
|
+
|
|
43
|
+
FizzBuzz の実装では、`transform` と `filter` でこの考え方をそのまま表現しています。
|
|
44
|
+
|
|
45
|
+
```scala
|
|
46
|
+
def transform(values: List[String], f: String => String): List[String] =
|
|
47
|
+
values.map(f)
|
|
48
|
+
|
|
49
|
+
def filter(values: List[String], predicate: String => Boolean): List[String] =
|
|
50
|
+
values.filter(predicate)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`transform` は変換ロジックを引数で受け取るため、`toUpperCase` 以外にも自由に差し替えできます。
|
|
54
|
+
|
|
55
|
+
## 10.4 関数合成
|
|
56
|
+
|
|
57
|
+
複数の小さな関数を組み合わせて新しい関数を作るのが関数合成です。実装は次のとおりです。
|
|
58
|
+
|
|
59
|
+
```scala
|
|
60
|
+
def compose(f: String => String, g: String => String): String => String =
|
|
61
|
+
f.compose(g)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
`f.compose(g)` は `f(g(x))` を意味します。つまり右から左へ適用されます。対して `andThen` は `g(f(x))` で、左から右へ適用されます。
|
|
65
|
+
|
|
66
|
+
```scala
|
|
67
|
+
val addBrackets: String => String = s => s"[$s]"
|
|
68
|
+
val toUpper: String => String = _.toUpperCase
|
|
69
|
+
|
|
70
|
+
val composed = addBrackets.compose(toUpper) // addBrackets(toUpper(x))
|
|
71
|
+
val piped = addBrackets.andThen(toUpper) // toUpper(addBrackets(x))
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
この違いを理解すると、パイプライン処理を意図通りに組み立てられます。
|
|
75
|
+
|
|
76
|
+
## 10.5 テスト
|
|
77
|
+
|
|
78
|
+
実装した関数型メソッドは、次のようにテストできます。
|
|
79
|
+
|
|
80
|
+
```scala
|
|
81
|
+
test("generateWith: カスタムルールで生成する") {
|
|
82
|
+
val customRule: Int => String = n => if n % 2 == 0 then "Even" else "Odd"
|
|
83
|
+
assert(FizzBuzz.generateWith(customRule)(2) === "Even")
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
test("compose: 2 つの関数を合成する") {
|
|
87
|
+
val addBrackets: String => String = s => s"[$s]"
|
|
88
|
+
val toUpper: String => String = _.toUpperCase
|
|
89
|
+
val combined = FizzBuzz.compose(addBrackets, toUpper)
|
|
90
|
+
assert(combined("Fizz") === "[FIZZ]")
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
高階関数や関数合成は抽象度が上がるため、入力と出力を明示したテストが特に重要です。
|
|
95
|
+
|
|
96
|
+
## 10.6 まとめ
|
|
97
|
+
|
|
98
|
+
この章では、Scala の関数型プログラミングの入口として次を確認しました。
|
|
99
|
+
|
|
100
|
+
- 高階関数 `generateWith` とカリー化
|
|
101
|
+
- `map`、`filter` を使うコレクション操作
|
|
102
|
+
- `compose` と `andThen` の違い
|
|
103
|
+
|
|
104
|
+
次章では、コレクション処理をさらに発展させ、`LazyList` による遅延評価を扱います。
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# 第 11 章: コレクション処理と遅延評価
|
|
2
|
+
|
|
3
|
+
## 11.1 はじめに
|
|
4
|
+
|
|
5
|
+
Scala の強みの 1 つは、表現力の高いコレクションライブラリです。`List` や `Vector` を使った宣言的な処理により、ループ中心の実装より意図を明確に書けます。
|
|
6
|
+
|
|
7
|
+
ここで重要なのが評価戦略です。
|
|
8
|
+
|
|
9
|
+
- 正格評価(eager evaluation): すぐに計算する
|
|
10
|
+
- 遅延評価(lazy evaluation): 必要になるまで計算しない
|
|
11
|
+
|
|
12
|
+
## 11.2 イミュータブルコレクション
|
|
13
|
+
|
|
14
|
+
Scala の標準コレクションは、デフォルトでイミュータブルを前提に設計されています。
|
|
15
|
+
|
|
16
|
+
- `List`: 連結リスト。先頭追加や再帰的処理と相性がよい
|
|
17
|
+
- `Vector`: ランダムアクセスに強い
|
|
18
|
+
- `Map`: キーと値の対応
|
|
19
|
+
- `Set`: 重複しない集合
|
|
20
|
+
|
|
21
|
+
イミュータブルな設計により、副作用を抑えやすくなり、テストしやすいコードになります。
|
|
22
|
+
|
|
23
|
+
## 11.3 コレクション操作の連鎖
|
|
24
|
+
|
|
25
|
+
`map`、`flatMap`、`filter`、`foldLeft` を連鎖させると、データ変換の流れを自然に表現できます。
|
|
26
|
+
|
|
27
|
+
```scala
|
|
28
|
+
val numbers = (1 to 20).toList
|
|
29
|
+
val result = numbers
|
|
30
|
+
.map(FizzBuzz.generate)
|
|
31
|
+
.filter(_ != "FizzBuzz")
|
|
32
|
+
.foldLeft(List.empty[String])((acc, v) => acc :+ v)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
for 内包表記も同じ考え方で使えます。
|
|
36
|
+
|
|
37
|
+
```scala
|
|
38
|
+
val result = for
|
|
39
|
+
n <- 1 to 100
|
|
40
|
+
value = FizzBuzz.generate(n)
|
|
41
|
+
if value != n.toString
|
|
42
|
+
yield value
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
for 内包表記は、`map`、`flatMap`、`filter` の組み合わせを読みやすく書くための構文糖衣です。
|
|
46
|
+
|
|
47
|
+
## 11.4 LazyList による遅延評価
|
|
48
|
+
|
|
49
|
+
FizzBuzz では無限シーケンスを `LazyList` で表現できます。
|
|
50
|
+
|
|
51
|
+
```scala
|
|
52
|
+
def lazyList: LazyList[String] =
|
|
53
|
+
LazyList.from(1).map(generate)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
`LazyList.from(1)` は 1 から始まる無限列です。`map(generate)` を付けても、実際の計算は要素を取り出すまで実行されません。
|
|
57
|
+
|
|
58
|
+
```scala
|
|
59
|
+
val firstFive = FizzBuzz.lazyList.take(5).toList
|
|
60
|
+
// List("1", "2", "Fizz", "4", "Buzz")
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
遅延評価の利点は次のとおりです。
|
|
64
|
+
|
|
65
|
+
- 必要な分だけ計算するため無駄が少ない
|
|
66
|
+
- 無限リストを安全に表現できる
|
|
67
|
+
- `take`、`drop`、`filter` を組み合わせた逐次処理を書きやすい
|
|
68
|
+
|
|
69
|
+
## 11.5 テスト
|
|
70
|
+
|
|
71
|
+
`LazyList` は「必要なときだけ評価される」ことを確認するテストが重要です。
|
|
72
|
+
|
|
73
|
+
```scala
|
|
74
|
+
test("lazyList: 遅延リストから最初の 5 要素を取得する") {
|
|
75
|
+
val result = FizzBuzz.lazyList.take(5).toList
|
|
76
|
+
assert(result === List("1", "2", "Fizz", "4", "Buzz"))
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
test("lazyList: 遅延リストから 15 番目の要素を取得する") {
|
|
80
|
+
assert(FizzBuzz.lazyList(14) === "FizzBuzz")
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
先頭数件だけを取り出すテストと、任意の位置の要素を直接参照するテストを組み合わせると、遅延シーケンスの振る舞いを網羅できます。
|
|
85
|
+
|
|
86
|
+
## 11.6 まとめ
|
|
87
|
+
|
|
88
|
+
この章では、Scala のコレクション処理と遅延評価を確認しました。
|
|
89
|
+
|
|
90
|
+
- イミュータブルコレクションを前提に実装する
|
|
91
|
+
- `map`、`flatMap`、`filter`、`foldLeft` を連鎖して処理を記述する
|
|
92
|
+
- `LazyList` で無限シーケンスと必要時評価を実現する
|
|
93
|
+
|
|
94
|
+
次章では、`Option` や `Either` を使った型安全なエラーハンドリングを扱います。
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# 第 12 章: エラーハンドリングと型安全性
|
|
2
|
+
|
|
3
|
+
## 12.1 はじめに
|
|
4
|
+
|
|
5
|
+
Scala では、例外を多用するよりも型でエラー可能性を表現する設計が推奨されます。コンパイル時に考慮漏れを減らせるためです。
|
|
6
|
+
|
|
7
|
+
この章では `Option`、`Either`、`Try`、`require` を使い、型安全なエラーハンドリングを整理します。
|
|
8
|
+
|
|
9
|
+
## 12.2 Option 型
|
|
10
|
+
|
|
11
|
+
`Option` は「値があるかもしれないし、ないかもしれない」を表現します。
|
|
12
|
+
|
|
13
|
+
```scala
|
|
14
|
+
def safeGenerate(number: Int): Option[String] =
|
|
15
|
+
if number > 0 then Some(generate(number))
|
|
16
|
+
else None
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
- `Some(value)`: 値あり
|
|
20
|
+
- `None`: 値なし
|
|
21
|
+
|
|
22
|
+
`Option` は `map`、`flatMap`、`getOrElse` と相性がよく、null チェックを置き換えられます。
|
|
23
|
+
|
|
24
|
+
```scala
|
|
25
|
+
val message = FizzBuzz.safeGenerate(3)
|
|
26
|
+
.map(v => s"結果: $v")
|
|
27
|
+
.getOrElse("入力が不正です")
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## 12.3 Either 型
|
|
31
|
+
|
|
32
|
+
`Either` は成功と失敗のどちらかを保持します。
|
|
33
|
+
|
|
34
|
+
```scala
|
|
35
|
+
def generateEither(number: Int): Either[String, String] =
|
|
36
|
+
if number > 0 then Right(generate(number))
|
|
37
|
+
else Left(s"正の整数が必要です: $number")
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
- `Right`: 成功値
|
|
41
|
+
- `Left`: エラー情報
|
|
42
|
+
|
|
43
|
+
`Either` を使うと、エラーを文字列やドメイン型で返せるため、例外より制御しやすくなります。複数処理の連鎖では for 内包表記も利用できます。
|
|
44
|
+
|
|
45
|
+
```scala
|
|
46
|
+
val result = for
|
|
47
|
+
a <- FizzBuzz.generateEither(3)
|
|
48
|
+
b <- FizzBuzz.generateEither(5)
|
|
49
|
+
yield s"$a, $b"
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## 12.4 Try 型
|
|
53
|
+
|
|
54
|
+
`Try` は例外を値として扱う型です。例外が起きうる処理を安全に包めます。
|
|
55
|
+
|
|
56
|
+
```scala
|
|
57
|
+
import scala.util.Try
|
|
58
|
+
|
|
59
|
+
val parsed: Try[Int] = Try("42".toInt)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`Try` は `Success` / `Failure` の 2 形です。`map` や `recover` と組み合わせると、例外処理を宣言的に記述できます。
|
|
63
|
+
|
|
64
|
+
## 12.5 require による事前条件
|
|
65
|
+
|
|
66
|
+
ドメインモデルの入力検証には `require` が使えます。
|
|
67
|
+
|
|
68
|
+
```scala
|
|
69
|
+
case class FizzBuzzValue(number: Int, value: String):
|
|
70
|
+
require(number > 0, s"数値は正の整数でなければなりません: $number")
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
不正な値でオブジェクトが作られることを防ぎ、ドメイン不変条件をコンストラクタ境界で守れます。
|
|
74
|
+
|
|
75
|
+
## 12.6 型安全な設計のまとめ
|
|
76
|
+
|
|
77
|
+
- `Option`: 値の有無を型で表現する
|
|
78
|
+
- `Either`: 成功 / 失敗の分岐を型で表現する
|
|
79
|
+
- `Try`: 例外を値として安全に扱う
|
|
80
|
+
- `require`: 事前条件を明示し、不正状態を早期に排除する
|
|
81
|
+
|
|
82
|
+
## 12.7 シリーズのまとめ
|
|
83
|
+
|
|
84
|
+
全 12 章を通して、FizzBuzz を題材に TDD と Scala の設計原則を段階的に学びました。
|
|
85
|
+
|
|
86
|
+
- TDD の基本サイクル(Red-Green-Refactor)
|
|
87
|
+
- 開発環境の自動化
|
|
88
|
+
- オブジェクト指向設計(ケースクラス、トレイト、パターンマッチ)
|
|
89
|
+
- 関数型プログラミング(高階関数、コレクション、型安全なエラーハンドリング)
|
|
90
|
+
- Scala の OOP と FP の統合
|
|
91
|
+
|
|
92
|
+
小さな題材でも、設計・テスト・リファクタリングを繰り返すことで、実務で使える設計力を着実に伸ばせます。
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# テスト駆動開発から始める Scala 入門
|
|
2
|
+
|
|
3
|
+
## 概要
|
|
4
|
+
|
|
5
|
+
本シリーズでは、テスト駆動開発(TDD)の実践を通じて Scala の特徴を学びます。FizzBuzz 問題を題材に、Red-Green-Refactor サイクルを体験しながら、Scala のオブジェクト指向と関数型プログラミングの両方を段階的に習得します。
|
|
6
|
+
|
|
7
|
+
## 対象読者
|
|
8
|
+
|
|
9
|
+
- プログラミングの基礎知識を持つ方
|
|
10
|
+
- TDD に興味がある方
|
|
11
|
+
- Scala や JVM 上の関数型プログラミングに興味がある方
|
|
12
|
+
|
|
13
|
+
## 前提条件
|
|
14
|
+
|
|
15
|
+
- Scala 3.x、sbt がインストールされていること
|
|
16
|
+
- テキストエディタまたは IDE が利用可能であること
|
|
17
|
+
- Git の基本操作ができること
|
|
18
|
+
|
|
19
|
+
## Scala の特徴
|
|
20
|
+
|
|
21
|
+
| 特徴 | 説明 |
|
|
22
|
+
|------|------|
|
|
23
|
+
| OOP と FP の統合 | オブジェクト指向と関数型プログラミングを自然に組み合わせ可能 |
|
|
24
|
+
| 型推論 | 強力な型推論により型アノテーションを最小限に抑制 |
|
|
25
|
+
| ケースクラス | 不変の値オブジェクトを簡潔に定義 |
|
|
26
|
+
| パターンマッチ | 網羅的で型安全な分岐処理 |
|
|
27
|
+
| トレイト | 柔軟なミックスインによるコード再利用 |
|
|
28
|
+
| コレクションライブラリ | 統一的な API による豊富なコレクション操作 |
|
|
29
|
+
| JVM 互換 | Java エコシステムとの完全な相互運用性 |
|
|
30
|
+
|
|
31
|
+
## 開発ツール
|
|
32
|
+
|
|
33
|
+
| ツール | 用途 |
|
|
34
|
+
|--------|------|
|
|
35
|
+
| sbt | ビルドツール・パッケージマネージャ |
|
|
36
|
+
| ScalaTest | テスティングフレームワーク |
|
|
37
|
+
| scalafmt | コードフォーマッタ |
|
|
38
|
+
| WartRemover | 静的解析(コード品質チェック) |
|
|
39
|
+
| Metals | Language Server Protocol 実装 |
|
|
40
|
+
|
|
41
|
+
## 目次
|
|
42
|
+
|
|
43
|
+
### 第 1 部: TDD の基本サイクル
|
|
44
|
+
|
|
45
|
+
1. [第 1 章: TODO リストと最初のテスト](./01-todo-list-and-first-test.md)
|
|
46
|
+
2. [第 2 章: 仮実装と三角測量](./02-fake-it-and-triangulation.md)
|
|
47
|
+
3. [第 3 章: 明白な実装とリファクタリング](./03-obvious-implementation-and-refactoring.md)
|
|
48
|
+
|
|
49
|
+
### 第 2 部: 開発環境と自動化
|
|
50
|
+
|
|
51
|
+
4. [第 4 章: バージョン管理と Conventional Commits](./04-version-control-and-conventional-commits.md)
|
|
52
|
+
5. [第 5 章: パッケージ管理と静的解析](./05-package-management-and-static-analysis.md)
|
|
53
|
+
6. [第 6 章: タスクランナーと CI/CD](./06-task-runner-and-ci-cd.md)
|
|
54
|
+
|
|
55
|
+
### 第 3 部: オブジェクト指向設計
|
|
56
|
+
|
|
57
|
+
7. [第 7 章: ケースクラスとトレイトによるポリモーフィズム](./07-case-classes-and-traits.md)
|
|
58
|
+
8. [第 8 章: パターンマッチとシールドトレイト](./08-pattern-matching-and-sealed-traits.md)
|
|
59
|
+
9. [第 9 章: パッケージとモジュール設計](./09-packages-and-module-design.md)
|
|
60
|
+
|
|
61
|
+
### 第 4 部: 関数型プログラミング
|
|
62
|
+
|
|
63
|
+
10. [第 10 章: 高階関数と関数合成](./10-higher-order-functions-and-composition.md)
|
|
64
|
+
11. [第 11 章: コレクション処理と遅延評価](./11-collections-and-lazy-evaluation.md)
|
|
65
|
+
12. [第 12 章: エラーハンドリングと型安全性](./12-error-handling-and-type-safety.md)
|