@k2works/claude-code-booster 2.7.1 → 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 -103
- 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/review/index.md +5 -0
- package/lib/assets/docs/strategy/index.md +15 -0
- package/lib/assets/docs/template/index.md +9 -5
- package/lib/assets/mkdocs.yml +33 -19
- package/package.json +1 -1
- package/lib/assets/docs/analysis/index.md +0 -8
- /package/lib/assets/docs/{analysis → strategy}/slide/.gitkeep +0 -0
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
# 第8章: Decorator パターン
|
|
2
|
+
|
|
3
|
+
## はじめに
|
|
4
|
+
|
|
5
|
+
Decorator パターンは、既存のオブジェクトに新しい機能を動的に追加するパターンです。このパターンを使用すると、サブクラス化による継承よりも柔軟な方法で機能を拡張できます。
|
|
6
|
+
|
|
7
|
+
関数型プログラミングでは、高階関数を使って関数をラップし、横断的関心事(ログ、キャッシュ、認証など)を追加します。本章では、形状のジャーナリングと関数デコレータについて学びます。
|
|
8
|
+
|
|
9
|
+
## 1. パターンの構造
|
|
10
|
+
|
|
11
|
+
Decorator パターンは以下の要素で構成されます:
|
|
12
|
+
|
|
13
|
+
- **Component**: デコレート対象の共通インターフェース
|
|
14
|
+
- **ConcreteComponent**: 具体的なコンポーネント
|
|
15
|
+
- **Decorator**: Component をラップし、追加機能を提供
|
|
16
|
+
|
|
17
|
+
```plantuml
|
|
18
|
+
@startuml
|
|
19
|
+
skinparam classAttributeIconSize 0
|
|
20
|
+
|
|
21
|
+
interface Component {
|
|
22
|
+
+operation()
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
class ConcreteComponent {
|
|
26
|
+
+operation()
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
class Decorator {
|
|
30
|
+
+wrapped: Component
|
|
31
|
+
+operation()
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
Component <|.. ConcreteComponent
|
|
35
|
+
Component <|.. Decorator
|
|
36
|
+
Decorator o--> Component : wraps
|
|
37
|
+
@enduml
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## 2. JournaledShape の例
|
|
41
|
+
|
|
42
|
+
### データ型の定義
|
|
43
|
+
|
|
44
|
+
形状オブジェクトに操作の履歴を記録する機能を追加するデコレータです。
|
|
45
|
+
|
|
46
|
+
```haskell
|
|
47
|
+
-- | Journal entry for shape operations
|
|
48
|
+
data JournalEntry
|
|
49
|
+
= TranslateEntry Double Double -- ^ Translation by (dx, dy)
|
|
50
|
+
| ScaleEntry Double -- ^ Scale by factor
|
|
51
|
+
deriving (Show, Eq)
|
|
52
|
+
|
|
53
|
+
-- | Shape with operation history
|
|
54
|
+
data JournaledShape = JournaledShape
|
|
55
|
+
{ jsJournal :: [JournalEntry] -- ^ History of operations
|
|
56
|
+
, jsShape :: Shape -- ^ The wrapped shape
|
|
57
|
+
} deriving (Show, Eq)
|
|
58
|
+
|
|
59
|
+
-- | Wrap a shape with journaling
|
|
60
|
+
journalShape :: Shape -> JournaledShape
|
|
61
|
+
journalShape shape = JournaledShape
|
|
62
|
+
{ jsJournal = []
|
|
63
|
+
, jsShape = shape
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
-- | Get the journal entries
|
|
67
|
+
getJournal :: JournaledShape -> [JournalEntry]
|
|
68
|
+
getJournal = jsJournal
|
|
69
|
+
|
|
70
|
+
-- | Get the underlying shape
|
|
71
|
+
getShape :: JournaledShape -> Shape
|
|
72
|
+
getShape = jsShape
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### デコレートされた操作
|
|
76
|
+
|
|
77
|
+
```haskell
|
|
78
|
+
-- | Translate a journaled shape
|
|
79
|
+
translateJournaled :: Double -> Double -> JournaledShape -> JournaledShape
|
|
80
|
+
translateJournaled dx dy js = JournaledShape
|
|
81
|
+
{ jsJournal = jsJournal js ++ [TranslateEntry dx dy]
|
|
82
|
+
, jsShape = translateShape dx dy (jsShape js)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
-- | Scale a journaled shape
|
|
86
|
+
scaleJournaled :: Double -> JournaledShape -> JournaledShape
|
|
87
|
+
scaleJournaled factor js = JournaledShape
|
|
88
|
+
{ jsJournal = jsJournal js ++ [ScaleEntry factor]
|
|
89
|
+
, jsShape = scaleShape factor (jsShape js)
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### 使用例
|
|
94
|
+
|
|
95
|
+
```haskell
|
|
96
|
+
-- 形状をデコレート
|
|
97
|
+
let journaledSquare = journalShape (Square (Point 0 0) 1)
|
|
98
|
+
& translateJournaled 2 3
|
|
99
|
+
& scaleJournaled 5
|
|
100
|
+
|
|
101
|
+
-- ジャーナルを確認
|
|
102
|
+
getJournal journaledSquare
|
|
103
|
+
-- [TranslateEntry 2 3, ScaleEntry 5]
|
|
104
|
+
|
|
105
|
+
-- 実際の形状を確認
|
|
106
|
+
getShape journaledSquare
|
|
107
|
+
-- Square (Point 2 3) 5
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## 3. 関数デコレータ
|
|
111
|
+
|
|
112
|
+
関数型プログラミングでは、高階関数を使って関数をデコレートします。
|
|
113
|
+
|
|
114
|
+
### ログ出力デコレータ
|
|
115
|
+
|
|
116
|
+
```haskell
|
|
117
|
+
-- | Add logging to a function (collects log entries)
|
|
118
|
+
withLogging :: String -> (a -> b) -> (a -> (b, [String]))
|
|
119
|
+
withLogging name f = \x ->
|
|
120
|
+
let result = f x
|
|
121
|
+
in (result, ["[LOG] " ++ name ++ " called", "[LOG] " ++ name ++ " returned"])
|
|
122
|
+
|
|
123
|
+
-- 使用例
|
|
124
|
+
let addLogged = withLogging "double" (* 2)
|
|
125
|
+
let (result, logs) = addLogged 5
|
|
126
|
+
-- result = 10
|
|
127
|
+
-- logs = ["[LOG] double called", "[LOG] double returned"]
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### リトライデコレータ
|
|
131
|
+
|
|
132
|
+
```haskell
|
|
133
|
+
-- | Add retry logic to a function that might fail
|
|
134
|
+
withRetry :: Int -> (a -> Either String b) -> (a -> Either String b)
|
|
135
|
+
withRetry maxRetries f = go 0
|
|
136
|
+
where
|
|
137
|
+
go attempts x
|
|
138
|
+
| attempts >= maxRetries = Left "Max retries exceeded"
|
|
139
|
+
| otherwise = case f x of
|
|
140
|
+
Right result -> Right result
|
|
141
|
+
Left _ -> go (attempts + 1) x
|
|
142
|
+
|
|
143
|
+
-- 使用例
|
|
144
|
+
let unreliable _ = Left "error" :: Either String String
|
|
145
|
+
let withRetries = withRetry 3 unreliable
|
|
146
|
+
withRetries () -- Left "Max retries exceeded"
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### キャッシュデコレータ
|
|
150
|
+
|
|
151
|
+
```haskell
|
|
152
|
+
-- | Add caching to a function (using a Map for pure memoization)
|
|
153
|
+
withCache :: Ord a => (a -> b) -> (Map a b -> a -> (b, Map a b))
|
|
154
|
+
withCache f = \cache x ->
|
|
155
|
+
case Map.lookup x cache of
|
|
156
|
+
Just cached -> (cached, cache)
|
|
157
|
+
Nothing ->
|
|
158
|
+
let result = f x
|
|
159
|
+
in (result, Map.insert x result cache)
|
|
160
|
+
|
|
161
|
+
-- 使用例
|
|
162
|
+
let expensiveFn x = x * x -- expensive computation
|
|
163
|
+
let cached = withCache expensiveFn
|
|
164
|
+
let (result1, cache1) = cached Map.empty 5 -- computes
|
|
165
|
+
let (result2, cache2) = cached cache1 5 -- cache hit
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### バリデーションデコレータ
|
|
169
|
+
|
|
170
|
+
```haskell
|
|
171
|
+
-- | Add validation to a function
|
|
172
|
+
withValidation :: (a -> Bool) -> String -> (a -> Either String b) -> (a -> Either String b)
|
|
173
|
+
withValidation validator errMsg f = \x ->
|
|
174
|
+
if validator x
|
|
175
|
+
then f x
|
|
176
|
+
else Left errMsg
|
|
177
|
+
|
|
178
|
+
-- 使用例
|
|
179
|
+
let positiveOnly = withValidation (> 0) "Must be positive" (\x -> Right (x * 2))
|
|
180
|
+
positiveOnly 5 -- Right 10
|
|
181
|
+
positiveOnly (-5) -- Left "Must be positive"
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## 4. デコレータの組み合わせ
|
|
185
|
+
|
|
186
|
+
複数のデコレータを組み合わせて使用できます。
|
|
187
|
+
|
|
188
|
+
```haskell
|
|
189
|
+
-- | Compose multiple function transformations
|
|
190
|
+
composeDecorators :: [a -> a] -> a -> a
|
|
191
|
+
composeDecorators = foldr (.) id
|
|
192
|
+
|
|
193
|
+
-- 使用例
|
|
194
|
+
let add1 = (+ 1) :: Int -> Int
|
|
195
|
+
let mul2 = (* 2)
|
|
196
|
+
let decorators = [add1, mul2] -- (x * 2) + 1
|
|
197
|
+
let composed = composeDecorators decorators
|
|
198
|
+
composed 5 -- 11 = (5 * 2) + 1
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### 組み合わせのシーケンス図
|
|
202
|
+
|
|
203
|
+
```plantuml
|
|
204
|
+
@startuml
|
|
205
|
+
actor Client
|
|
206
|
+
participant "withLogging" as logging
|
|
207
|
+
participant "withCache" as cache
|
|
208
|
+
participant "base-fn" as base
|
|
209
|
+
|
|
210
|
+
Client -> logging : call(args)
|
|
211
|
+
activate logging
|
|
212
|
+
logging -> logging : log "called with args"
|
|
213
|
+
|
|
214
|
+
logging -> cache : call(args)
|
|
215
|
+
activate cache
|
|
216
|
+
|
|
217
|
+
alt キャッシュヒット
|
|
218
|
+
cache -> cache : return cached value
|
|
219
|
+
else キャッシュミス
|
|
220
|
+
cache -> base : call(args)
|
|
221
|
+
activate base
|
|
222
|
+
base --> cache : result
|
|
223
|
+
deactivate base
|
|
224
|
+
cache -> cache : store in cache
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
cache --> logging : result
|
|
228
|
+
deactivate cache
|
|
229
|
+
|
|
230
|
+
logging -> logging : log "returned result"
|
|
231
|
+
logging --> Client : result
|
|
232
|
+
deactivate logging
|
|
233
|
+
|
|
234
|
+
note right
|
|
235
|
+
デコレータは外側から内側へ
|
|
236
|
+
順番に適用されます
|
|
237
|
+
end note
|
|
238
|
+
@enduml
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## 5. カウンタ付き操作
|
|
242
|
+
|
|
243
|
+
```haskell
|
|
244
|
+
-- | Result with call count
|
|
245
|
+
data CountedResult a = CountedResult
|
|
246
|
+
{ crResult :: a
|
|
247
|
+
, crCount :: Int
|
|
248
|
+
} deriving (Show, Eq)
|
|
249
|
+
|
|
250
|
+
-- | Wrap a function to count calls
|
|
251
|
+
withCounter :: (a -> b) -> ([a] -> [CountedResult b])
|
|
252
|
+
withCounter f = zipWith (\i x -> CountedResult (f x) i) [1..]
|
|
253
|
+
|
|
254
|
+
-- 使用例
|
|
255
|
+
let counted = withCounter (* 2)
|
|
256
|
+
counted [1, 2, 3]
|
|
257
|
+
-- [CountedResult 2 1, CountedResult 4 2, CountedResult 6 3]
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
## 6. パターンの利点
|
|
261
|
+
|
|
262
|
+
1. **単一責任の原則**: 各デコレータは一つの機能のみを追加
|
|
263
|
+
2. **開放/閉鎖の原則**: 既存コードを変更せずに機能を追加
|
|
264
|
+
3. **柔軟な組み合わせ**: 必要な機能だけを選択して組み合わせ可能
|
|
265
|
+
4. **実行時の決定**: どのデコレータを適用するか実行時に決定可能
|
|
266
|
+
|
|
267
|
+
## 7. Haskell での特徴
|
|
268
|
+
|
|
269
|
+
Haskell での Decorator パターンの実装には以下の特徴があります:
|
|
270
|
+
|
|
271
|
+
1. **高階関数**: 関数を引数に取り、新しい関数を返す
|
|
272
|
+
2. **純粋性**: 副作用を避け、状態はデータ構造で明示的に管理
|
|
273
|
+
3. **イミュータブルなデータ**: デコレート後も元のデータは変更されない
|
|
274
|
+
4. **合成のしやすさ**: `(.)` 演算子や `foldr` で簡単に組み合わせ可能
|
|
275
|
+
5. **型安全性**: 型システムによりデコレータの適用ミスを防止
|
|
276
|
+
|
|
277
|
+
### Haskell 特有の考慮事項
|
|
278
|
+
|
|
279
|
+
```haskell
|
|
280
|
+
-- Haskell では副作用を持つ操作は IO モナドを使用
|
|
281
|
+
-- 純粋なデコレータでは状態を明示的に渡す必要がある
|
|
282
|
+
|
|
283
|
+
-- 純粋なキャッシュ(状態を明示的に渡す)
|
|
284
|
+
withCache :: Ord a => (a -> b) -> (Map a b -> a -> (b, Map a b))
|
|
285
|
+
|
|
286
|
+
-- IO モナドを使ったキャッシュ(内部状態を持つ)
|
|
287
|
+
withCacheIO :: Ord a => (a -> b) -> IO (a -> IO b)
|
|
288
|
+
withCacheIO f = do
|
|
289
|
+
ref <- newIORef Map.empty
|
|
290
|
+
return $ \x -> do
|
|
291
|
+
cache <- readIORef ref
|
|
292
|
+
case Map.lookup x cache of
|
|
293
|
+
Just v -> return v
|
|
294
|
+
Nothing -> do
|
|
295
|
+
let v = f x
|
|
296
|
+
modifyIORef ref (Map.insert x v)
|
|
297
|
+
return v
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
## まとめ
|
|
301
|
+
|
|
302
|
+
本章では、Decorator パターンについて学びました:
|
|
303
|
+
|
|
304
|
+
1. **JournaledShape**: 形状操作の履歴を記録するデコレータ
|
|
305
|
+
2. **関数デコレータ**: ログ、リトライ、キャッシュなどの横断的関心事
|
|
306
|
+
3. **デコレータの組み合わせ**: 複数のデコレータを柔軟に組み合わせ
|
|
307
|
+
|
|
308
|
+
Decorator パターンは、既存のコードを変更せずに機能を拡張する強力なパターンです。Haskell では高階関数と純粋関数を活用することで、型安全で合成しやすいデコレータを実装できます。
|
|
309
|
+
|
|
310
|
+
## 参考コード
|
|
311
|
+
|
|
312
|
+
本章のコード例は以下のファイルで確認できます:
|
|
313
|
+
|
|
314
|
+
- ソースコード: `apps/haskell/part3/src/DecoratorPattern.hs`
|
|
315
|
+
- テストコード: `apps/haskell/part3/test/DecoratorPatternSpec.hs`
|
|
316
|
+
|
|
317
|
+
## 次章予告
|
|
318
|
+
|
|
319
|
+
次章では、**Adapter パターン**について学びます。異なるインターフェース間の変換とレガシーシステムとの統合を探ります。
|
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
# 第9章: Adapter パターン
|
|
2
|
+
|
|
3
|
+
## はじめに
|
|
4
|
+
|
|
5
|
+
Adapter パターンは、既存のクラスのインターフェースを、クライアントが期待する別のインターフェースに変換するパターンです。このパターンを使用すると、互換性のないインターフェースを持つクラス同士を連携させることができます。
|
|
6
|
+
|
|
7
|
+
本章では、可変強度ライトのアダプター、データフォーマット変換、温度・通貨変換について学びます。
|
|
8
|
+
|
|
9
|
+
## 1. パターンの構造
|
|
10
|
+
|
|
11
|
+
Adapter パターンは以下の要素で構成されます:
|
|
12
|
+
|
|
13
|
+
- **Target**: クライアントが期待するインターフェース
|
|
14
|
+
- **Adaptee**: 既存のクラス(適応される側)
|
|
15
|
+
- **Adapter**: Target インターフェースを実装し、Adaptee を使用
|
|
16
|
+
|
|
17
|
+
```plantuml
|
|
18
|
+
@startuml
|
|
19
|
+
skinparam classAttributeIconSize 0
|
|
20
|
+
|
|
21
|
+
interface Target {
|
|
22
|
+
+request()
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
class Adaptee {
|
|
26
|
+
+specificRequest()
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
class Adapter {
|
|
30
|
+
+adaptee: Adaptee
|
|
31
|
+
+request()
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
class Client {
|
|
35
|
+
+operation()
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
Adapter ..|> Target
|
|
39
|
+
Adapter --> Adaptee : adapts
|
|
40
|
+
Client --> Target : uses
|
|
41
|
+
@enduml
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## 2. VariableLight の例
|
|
45
|
+
|
|
46
|
+
### Switchable インターフェース (Target)
|
|
47
|
+
|
|
48
|
+
```haskell
|
|
49
|
+
-- | Result of a switch operation
|
|
50
|
+
data SwitchResult = SwitchResult
|
|
51
|
+
{ srOn :: Bool
|
|
52
|
+
, srIntensity :: Maybe Int
|
|
53
|
+
} deriving (Show, Eq)
|
|
54
|
+
|
|
55
|
+
-- | Switchable interface - the target interface
|
|
56
|
+
class Switchable a where
|
|
57
|
+
switchTurnOn :: a -> (a, SwitchResult)
|
|
58
|
+
switchTurnOff :: a -> (a, SwitchResult)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### VariableLight (Adaptee)
|
|
62
|
+
|
|
63
|
+
可変強度を持つライトは、単純なオン/オフではなく、強度を指定する必要があります。
|
|
64
|
+
|
|
65
|
+
```haskell
|
|
66
|
+
-- | Variable light with intensity control
|
|
67
|
+
data VariableLight = VariableLight
|
|
68
|
+
{ vlIntensity :: Int -- ^ 0-100
|
|
69
|
+
} deriving (Show, Eq)
|
|
70
|
+
|
|
71
|
+
-- | Set the light intensity (the adaptee's specific method)
|
|
72
|
+
setLightIntensity :: Int -> VariableLight -> VariableLight
|
|
73
|
+
setLightIntensity intensity vl = vl { vlIntensity = max 0 (min 100 intensity) }
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### VariableLightAdapter (Adapter)
|
|
77
|
+
|
|
78
|
+
```haskell
|
|
79
|
+
-- | Adapter that wraps VariableLight and provides Switchable interface
|
|
80
|
+
data VariableLightAdapter = VariableLightAdapter
|
|
81
|
+
{ vlaLight :: VariableLight
|
|
82
|
+
, vlaMinIntensity :: Int
|
|
83
|
+
, vlaMaxIntensity :: Int
|
|
84
|
+
} deriving (Show, Eq)
|
|
85
|
+
|
|
86
|
+
-- | Create a variable light adapter
|
|
87
|
+
makeVariableLightAdapter :: Int -> Int -> VariableLightAdapter
|
|
88
|
+
makeVariableLightAdapter minI maxI = VariableLightAdapter
|
|
89
|
+
{ vlaLight = VariableLight 0
|
|
90
|
+
, vlaMinIntensity = minI
|
|
91
|
+
, vlaMaxIntensity = maxI
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
-- | Turn on through the adapter
|
|
95
|
+
adaptedTurnOn :: VariableLightAdapter -> (VariableLightAdapter, SwitchResult)
|
|
96
|
+
adaptedTurnOn adapter =
|
|
97
|
+
let newLight = setLightIntensity (vlaMaxIntensity adapter) (vlaLight adapter)
|
|
98
|
+
newAdapter = adapter { vlaLight = newLight }
|
|
99
|
+
result = SwitchResult True (Just $ vlIntensity newLight)
|
|
100
|
+
in (newAdapter, result)
|
|
101
|
+
|
|
102
|
+
-- | Turn off through the adapter
|
|
103
|
+
adaptedTurnOff :: VariableLightAdapter -> (VariableLightAdapter, SwitchResult)
|
|
104
|
+
adaptedTurnOff adapter =
|
|
105
|
+
let newLight = setLightIntensity (vlaMinIntensity adapter) (vlaLight adapter)
|
|
106
|
+
newAdapter = adapter { vlaLight = newLight }
|
|
107
|
+
result = SwitchResult False (Just $ vlIntensity newLight)
|
|
108
|
+
in (newAdapter, result)
|
|
109
|
+
|
|
110
|
+
-- Make VariableLightAdapter an instance of Switchable
|
|
111
|
+
instance Switchable VariableLightAdapter where
|
|
112
|
+
switchTurnOn = adaptedTurnOn
|
|
113
|
+
switchTurnOff = adaptedTurnOff
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### 使用例
|
|
117
|
+
|
|
118
|
+
```haskell
|
|
119
|
+
-- アダプターを作成(最小0、最大100)
|
|
120
|
+
let adapter = makeVariableLightAdapter 0 100
|
|
121
|
+
|
|
122
|
+
-- クライアントはSwitchableインターフェースで操作
|
|
123
|
+
let (onAdapter, onResult) = switchTurnOn adapter
|
|
124
|
+
-- onResult = SwitchResult True (Just 100)
|
|
125
|
+
|
|
126
|
+
let (offAdapter, offResult) = switchTurnOff onAdapter
|
|
127
|
+
-- offResult = SwitchResult False (Just 0)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## 3. データフォーマットアダプター
|
|
131
|
+
|
|
132
|
+
### ユーザーフォーマット変換
|
|
133
|
+
|
|
134
|
+
異なるシステム間でデータフォーマットが異なる場合、アダプターを使って変換します。
|
|
135
|
+
|
|
136
|
+
```haskell
|
|
137
|
+
-- | Old user format (legacy system)
|
|
138
|
+
data OldUserFormat = OldUserFormat
|
|
139
|
+
{ oufFirstName :: String
|
|
140
|
+
, oufLastName :: String
|
|
141
|
+
, oufEmailAddress :: String
|
|
142
|
+
, oufPhoneNumber :: String
|
|
143
|
+
} deriving (Show, Eq)
|
|
144
|
+
|
|
145
|
+
-- | Metadata for converted users
|
|
146
|
+
data UserMetadata = UserMetadata
|
|
147
|
+
{ umMigrated :: Bool
|
|
148
|
+
, umOriginalFormat :: String
|
|
149
|
+
} deriving (Show, Eq)
|
|
150
|
+
|
|
151
|
+
-- | New user format (modern system)
|
|
152
|
+
data NewUserFormat = NewUserFormat
|
|
153
|
+
{ nufName :: String
|
|
154
|
+
, nufEmail :: String
|
|
155
|
+
, nufPhone :: String
|
|
156
|
+
, nufMetadata :: Maybe UserMetadata
|
|
157
|
+
} deriving (Show, Eq)
|
|
158
|
+
|
|
159
|
+
-- | Adapt old user format to new format
|
|
160
|
+
adaptOldToNew :: OldUserFormat -> NewUserFormat
|
|
161
|
+
adaptOldToNew old = NewUserFormat
|
|
162
|
+
{ nufName = oufLastName old ++ " " ++ oufFirstName old
|
|
163
|
+
, nufEmail = oufEmailAddress old
|
|
164
|
+
, nufPhone = oufPhoneNumber old
|
|
165
|
+
, nufMetadata = Just UserMetadata
|
|
166
|
+
{ umMigrated = True
|
|
167
|
+
, umOriginalFormat = "old"
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
-- | Adapt new user format to old format
|
|
172
|
+
adaptNewToOld :: NewUserFormat -> OldUserFormat
|
|
173
|
+
adaptNewToOld new =
|
|
174
|
+
case nonEmpty (words (nufName new)) of
|
|
175
|
+
Nothing -> OldUserFormat "" "" (nufEmail new) (nufPhone new)
|
|
176
|
+
Just ne -> OldUserFormat
|
|
177
|
+
{ oufFirstName = unwords (NE.tail ne)
|
|
178
|
+
, oufLastName = NE.head ne
|
|
179
|
+
, oufEmailAddress = nufEmail new
|
|
180
|
+
, oufPhoneNumber = nufPhone new
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### 使用例
|
|
185
|
+
|
|
186
|
+
```haskell
|
|
187
|
+
-- 旧フォーマット → 新フォーマット
|
|
188
|
+
let oldUser = OldUserFormat "Taro" "Yamada" "taro@example.com" "090-1234-5678"
|
|
189
|
+
let newUser = adaptOldToNew oldUser
|
|
190
|
+
-- newUser = NewUserFormat
|
|
191
|
+
-- { nufName = "Yamada Taro"
|
|
192
|
+
-- , nufEmail = "taro@example.com"
|
|
193
|
+
-- , nufPhone = "090-1234-5678"
|
|
194
|
+
-- , nufMetadata = Just UserMetadata {umMigrated = True, umOriginalFormat = "old"}
|
|
195
|
+
-- }
|
|
196
|
+
|
|
197
|
+
-- 新フォーマット → 旧フォーマット
|
|
198
|
+
let back = adaptNewToOld newUser
|
|
199
|
+
-- back = OldUserFormat "Taro" "Yamada" "taro@example.com" "090-1234-5678"
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## 4. 温度アダプター
|
|
203
|
+
|
|
204
|
+
```haskell
|
|
205
|
+
-- | Temperature in Celsius
|
|
206
|
+
newtype Celsius = Celsius { getCelsius :: Double }
|
|
207
|
+
deriving (Show, Eq)
|
|
208
|
+
|
|
209
|
+
-- | Temperature in Fahrenheit
|
|
210
|
+
newtype Fahrenheit = Fahrenheit { getFahrenheit :: Double }
|
|
211
|
+
deriving (Show, Eq)
|
|
212
|
+
|
|
213
|
+
-- | Convert Celsius to Fahrenheit
|
|
214
|
+
celsiusToFahrenheit :: Celsius -> Fahrenheit
|
|
215
|
+
celsiusToFahrenheit (Celsius c) = Fahrenheit (c * 9/5 + 32)
|
|
216
|
+
|
|
217
|
+
-- | Convert Fahrenheit to Celsius
|
|
218
|
+
fahrenheitToCelsius :: Fahrenheit -> Celsius
|
|
219
|
+
fahrenheitToCelsius (Fahrenheit f) = Celsius ((f - 32) * 5/9)
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### 使用例
|
|
223
|
+
|
|
224
|
+
```haskell
|
|
225
|
+
let freezing = Celsius 0
|
|
226
|
+
let boiling = Celsius 100
|
|
227
|
+
|
|
228
|
+
celsiusToFahrenheit freezing -- Fahrenheit 32
|
|
229
|
+
celsiusToFahrenheit boiling -- Fahrenheit 212
|
|
230
|
+
|
|
231
|
+
-- 往復変換
|
|
232
|
+
let temp = Celsius 25
|
|
233
|
+
let converted = fahrenheitToCelsius (celsiusToFahrenheit temp)
|
|
234
|
+
-- converted ≈ Celsius 25
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## 5. 通貨アダプター
|
|
238
|
+
|
|
239
|
+
```haskell
|
|
240
|
+
-- | US Dollars
|
|
241
|
+
newtype USD = USD { getUsd :: Double }
|
|
242
|
+
deriving (Show, Eq)
|
|
243
|
+
|
|
244
|
+
-- | Euros
|
|
245
|
+
newtype EUR = EUR { getEur :: Double }
|
|
246
|
+
deriving (Show, Eq)
|
|
247
|
+
|
|
248
|
+
-- | Japanese Yen
|
|
249
|
+
newtype JPY = JPY { getJpy :: Double }
|
|
250
|
+
deriving (Show, Eq)
|
|
251
|
+
|
|
252
|
+
-- | Convert USD to EUR (simplified rate)
|
|
253
|
+
convertUsdToEur :: USD -> EUR
|
|
254
|
+
convertUsdToEur (USD usd) = EUR (usd * 0.85)
|
|
255
|
+
|
|
256
|
+
-- | Convert USD to JPY (simplified rate)
|
|
257
|
+
convertUsdToJpy :: USD -> JPY
|
|
258
|
+
convertUsdToJpy (USD usd) = JPY (usd * 110)
|
|
259
|
+
|
|
260
|
+
-- | Convert EUR to USD
|
|
261
|
+
convertEurToUsd :: EUR -> USD
|
|
262
|
+
convertEurToUsd (EUR eur) = USD (eur / 0.85)
|
|
263
|
+
|
|
264
|
+
-- | Convert JPY to USD
|
|
265
|
+
convertJpyToUsd :: JPY -> USD
|
|
266
|
+
convertJpyToUsd (JPY jpy) = USD (jpy / 110)
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## 6. 汎用アダプター
|
|
270
|
+
|
|
271
|
+
```haskell
|
|
272
|
+
-- | Generic bidirectional adapter
|
|
273
|
+
data Adapter a b = Adapter
|
|
274
|
+
{ adapterTo :: a -> b -- ^ Convert from A to B
|
|
275
|
+
, adapterFrom :: b -> a -- ^ Convert from B to A
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
-- | Apply adapter to convert from A to B
|
|
279
|
+
adapt :: Adapter a b -> a -> b
|
|
280
|
+
adapt = adapterTo
|
|
281
|
+
|
|
282
|
+
-- | Apply adapter to convert from B to A
|
|
283
|
+
adaptBack :: Adapter a b -> b -> a
|
|
284
|
+
adaptBack = adapterFrom
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### 使用例
|
|
288
|
+
|
|
289
|
+
```haskell
|
|
290
|
+
-- 温度変換アダプター
|
|
291
|
+
let tempAdapter = Adapter
|
|
292
|
+
{ adapterTo = \(Celsius c) -> Fahrenheit (c * 9/5 + 32)
|
|
293
|
+
, adapterFrom = \(Fahrenheit f) -> Celsius ((f - 32) * 5/9)
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
adapt tempAdapter (Celsius 0) -- Fahrenheit 32
|
|
297
|
+
adaptBack tempAdapter (Fahrenheit 32) -- Celsius 0
|
|
298
|
+
|
|
299
|
+
-- Int <-> String アダプター
|
|
300
|
+
let intStringAdapter = Adapter
|
|
301
|
+
{ adapterTo = show :: Int -> String
|
|
302
|
+
, adapterFrom = read
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
adapt intStringAdapter 42 -- "42"
|
|
306
|
+
adaptBack intStringAdapter "42" -- 42
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
## 7. パターンの利点
|
|
310
|
+
|
|
311
|
+
1. **既存コードの再利用**: 既存のクラスを変更せずに新しいインターフェースで使用
|
|
312
|
+
2. **単一責任の原則**: インターフェース変換のロジックを分離
|
|
313
|
+
3. **開放/閉鎖の原則**: 新しいアダプターを追加しても既存コードは変更不要
|
|
314
|
+
4. **レガシーシステムとの統合**: 古いシステムと新しいシステムを連携
|
|
315
|
+
|
|
316
|
+
## 8. Haskell での特徴
|
|
317
|
+
|
|
318
|
+
Haskell での Adapter パターンの実装には以下の特徴があります:
|
|
319
|
+
|
|
320
|
+
1. **型クラス**: ターゲットインターフェースを型クラスとして定義
|
|
321
|
+
2. **newtype**: 異なるドメインの値を型で区別(Celsius, Fahrenheit など)
|
|
322
|
+
3. **関数による変換**: 単純なデータ変換は純粋関数で直接実装
|
|
323
|
+
4. **イミュータブルなデータ**: 変換後も元のデータは変更されない
|
|
324
|
+
5. **合成のしやすさ**: 複数のアダプターを組み合わせ可能
|
|
325
|
+
|
|
326
|
+
### 型クラスによるインターフェース
|
|
327
|
+
|
|
328
|
+
```haskell
|
|
329
|
+
-- 型クラスでターゲットインターフェースを定義
|
|
330
|
+
class Switchable a where
|
|
331
|
+
switchTurnOn :: a -> (a, SwitchResult)
|
|
332
|
+
switchTurnOff :: a -> (a, SwitchResult)
|
|
333
|
+
|
|
334
|
+
-- 任意の型をインスタンスにできる
|
|
335
|
+
instance Switchable VariableLightAdapter where
|
|
336
|
+
switchTurnOn = adaptedTurnOn
|
|
337
|
+
switchTurnOff = adaptedTurnOff
|
|
338
|
+
|
|
339
|
+
-- ジェネリックな関数で使用
|
|
340
|
+
engageSwitch :: Switchable a => a -> (a, SwitchResult, SwitchResult)
|
|
341
|
+
engageSwitch s =
|
|
342
|
+
let (s1, onResult) = switchTurnOn s
|
|
343
|
+
(s2, offResult) = switchTurnOff s1
|
|
344
|
+
in (s2, onResult, offResult)
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### newtype による型安全性
|
|
348
|
+
|
|
349
|
+
```haskell
|
|
350
|
+
-- newtype を使うことで、同じ内部表現でも異なる型として扱える
|
|
351
|
+
newtype Celsius = Celsius Double
|
|
352
|
+
newtype Fahrenheit = Fahrenheit Double
|
|
353
|
+
|
|
354
|
+
-- コンパイル時に型チェックされる
|
|
355
|
+
add :: Celsius -> Celsius -> Celsius
|
|
356
|
+
add (Celsius a) (Celsius b) = Celsius (a + b)
|
|
357
|
+
|
|
358
|
+
-- これはコンパイルエラーになる
|
|
359
|
+
-- add (Celsius 10) (Fahrenheit 50) -- 型不一致
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
## まとめ
|
|
363
|
+
|
|
364
|
+
本章では、Adapter パターンについて学びました:
|
|
365
|
+
|
|
366
|
+
1. **VariableLightAdapter**: 可変強度ライトを単純なオン/オフインターフェースに適応
|
|
367
|
+
2. **データフォーマットアダプター**: 異なるデータ形式間の変換
|
|
368
|
+
3. **温度・通貨アダプター**: 単位変換の実装
|
|
369
|
+
4. **汎用アダプター**: 双方向変換を抽象化
|
|
370
|
+
|
|
371
|
+
Adapter パターンは、既存のコードを変更せずに異なるシステムを連携させる際に非常に有効です。Haskell では型クラスと newtype を活用することで、型安全で再利用性の高いアダプターを実装できます。
|
|
372
|
+
|
|
373
|
+
## 参考コード
|
|
374
|
+
|
|
375
|
+
本章のコード例は以下のファイルで確認できます:
|
|
376
|
+
|
|
377
|
+
- ソースコード: `apps/haskell/part3/src/AdapterPattern.hs`
|
|
378
|
+
- テストコード: `apps/haskell/part3/test/AdapterPatternSpec.hs`
|
|
379
|
+
|
|
380
|
+
## 次章予告
|
|
381
|
+
|
|
382
|
+
次章では、**Strategy パターン**について学びます。アルゴリズムをカプセル化し、実行時に切り替える方法を探ります。
|