@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.
Files changed (524) hide show
  1. package/lib/assets/docs/article/functional-desgin-ppp/all/01-immutability-and-data-transformation.md +475 -0
  2. package/lib/assets/docs/article/functional-desgin-ppp/all/02-function-composition.md +519 -0
  3. package/lib/assets/docs/article/functional-desgin-ppp/all/03-polymorphism.md +537 -0
  4. package/lib/assets/docs/article/functional-desgin-ppp/all/04-data-validation.md +300 -0
  5. package/lib/assets/docs/article/functional-desgin-ppp/all/05-property-based-testing.md +320 -0
  6. package/lib/assets/docs/article/functional-desgin-ppp/all/06-tdd-and-functional.md +498 -0
  7. package/lib/assets/docs/article/functional-desgin-ppp/all/07-composite-pattern.md +298 -0
  8. package/lib/assets/docs/article/functional-desgin-ppp/all/08-decorator-pattern.md +291 -0
  9. package/lib/assets/docs/article/functional-desgin-ppp/all/09-adapter-pattern.md +336 -0
  10. package/lib/assets/docs/article/functional-desgin-ppp/all/10-strategy-pattern.md +303 -0
  11. package/lib/assets/docs/article/functional-desgin-ppp/all/11-command-pattern.md +286 -0
  12. package/lib/assets/docs/article/functional-desgin-ppp/all/12-visitor-pattern.md +322 -0
  13. package/lib/assets/docs/article/functional-desgin-ppp/all/13-abstract-factory-pattern.md +319 -0
  14. package/lib/assets/docs/article/functional-desgin-ppp/all/14-abstract-server-pattern.md +365 -0
  15. package/lib/assets/docs/article/functional-desgin-ppp/all/15-gossiping-bus-drivers.md +156 -0
  16. package/lib/assets/docs/article/functional-desgin-ppp/all/16-payroll-system.md +178 -0
  17. package/lib/assets/docs/article/functional-desgin-ppp/all/17-video-rental-system.md +312 -0
  18. package/lib/assets/docs/article/functional-desgin-ppp/all/18-concurrency-system.md +287 -0
  19. package/lib/assets/docs/article/functional-desgin-ppp/all/19-wa-tor-simulation.md +286 -0
  20. package/lib/assets/docs/article/functional-desgin-ppp/all/20-pattern-interactions.md +274 -0
  21. package/lib/assets/docs/article/functional-desgin-ppp/all/21-best-practices.md +294 -0
  22. package/lib/assets/docs/article/functional-desgin-ppp/all/22-oo-to-fp-migration.md +337 -0
  23. package/lib/assets/docs/article/functional-desgin-ppp/all/index.md +388 -0
  24. package/lib/assets/docs/article/functional-desgin-ppp/clojure/01-immutability-and-data-transformation.md +271 -0
  25. package/lib/assets/docs/article/functional-desgin-ppp/clojure/02-function-composition.md +380 -0
  26. package/lib/assets/docs/article/functional-desgin-ppp/clojure/03-polymorphism.md +384 -0
  27. package/lib/assets/docs/article/functional-desgin-ppp/clojure/04-clojure-spec.md +350 -0
  28. package/lib/assets/docs/article/functional-desgin-ppp/clojure/05-property-based-testing.md +352 -0
  29. package/lib/assets/docs/article/functional-desgin-ppp/clojure/06-tdd-in-functional.md +383 -0
  30. package/lib/assets/docs/article/functional-desgin-ppp/clojure/07-composite-pattern.md +529 -0
  31. package/lib/assets/docs/article/functional-desgin-ppp/clojure/08-decorator-pattern.md +395 -0
  32. package/lib/assets/docs/article/functional-desgin-ppp/clojure/09-adapter-pattern.md +399 -0
  33. package/lib/assets/docs/article/functional-desgin-ppp/clojure/10-strategy-pattern.md +485 -0
  34. package/lib/assets/docs/article/functional-desgin-ppp/clojure/11-command-pattern.md +566 -0
  35. package/lib/assets/docs/article/functional-desgin-ppp/clojure/12-visitor-pattern.md +567 -0
  36. package/lib/assets/docs/article/functional-desgin-ppp/clojure/13-abstract-factory-pattern.md +475 -0
  37. package/lib/assets/docs/article/functional-desgin-ppp/clojure/14-abstract-server-pattern.md +462 -0
  38. package/lib/assets/docs/article/functional-desgin-ppp/clojure/15-gossiping-bus-drivers.md +323 -0
  39. package/lib/assets/docs/article/functional-desgin-ppp/clojure/16-payroll-system.md +401 -0
  40. package/lib/assets/docs/article/functional-desgin-ppp/clojure/17-video-rental-system.md +450 -0
  41. package/lib/assets/docs/article/functional-desgin-ppp/clojure/18-concurrency-system.md +475 -0
  42. package/lib/assets/docs/article/functional-desgin-ppp/clojure/19-wator-simulation.md +739 -0
  43. package/lib/assets/docs/article/functional-desgin-ppp/clojure/20-pattern-interactions.md +562 -0
  44. package/lib/assets/docs/article/functional-desgin-ppp/clojure/21-best-practices.md +506 -0
  45. package/lib/assets/docs/article/functional-desgin-ppp/clojure/22-oo-to-fp-migration.md +526 -0
  46. package/lib/assets/docs/article/functional-desgin-ppp/clojure/index.md +197 -0
  47. package/lib/assets/docs/article/functional-desgin-ppp/elixir/01-immutability-and-data-transformation.md +381 -0
  48. package/lib/assets/docs/article/functional-desgin-ppp/elixir/02-function-composition.md +374 -0
  49. package/lib/assets/docs/article/functional-desgin-ppp/elixir/03-polymorphism.md +375 -0
  50. package/lib/assets/docs/article/functional-desgin-ppp/elixir/04-data-validation.md +195 -0
  51. package/lib/assets/docs/article/functional-desgin-ppp/elixir/05-property-based-testing.md +268 -0
  52. package/lib/assets/docs/article/functional-desgin-ppp/elixir/06-tdd-and-fp.md +294 -0
  53. package/lib/assets/docs/article/functional-desgin-ppp/elixir/07-effects-and-pure-functions.md +164 -0
  54. package/lib/assets/docs/article/functional-desgin-ppp/elixir/08-error-handling-strategies.md +168 -0
  55. package/lib/assets/docs/article/functional-desgin-ppp/elixir/09-io-and-external-systems.md +254 -0
  56. package/lib/assets/docs/article/functional-desgin-ppp/elixir/10-concurrency-patterns.md +269 -0
  57. package/lib/assets/docs/article/functional-desgin-ppp/elixir/11-command-pattern.md +148 -0
  58. package/lib/assets/docs/article/functional-desgin-ppp/elixir/12-visitor-pattern.md +176 -0
  59. package/lib/assets/docs/article/functional-desgin-ppp/elixir/13-abstract-factory-pattern.md +604 -0
  60. package/lib/assets/docs/article/functional-desgin-ppp/elixir/14-abstract-server-pattern.md +729 -0
  61. package/lib/assets/docs/article/functional-desgin-ppp/elixir/15-gossiping-bus-drivers.md +291 -0
  62. package/lib/assets/docs/article/functional-desgin-ppp/elixir/16-payroll-system.md +420 -0
  63. package/lib/assets/docs/article/functional-desgin-ppp/elixir/17-video-rental-system.md +319 -0
  64. package/lib/assets/docs/article/functional-desgin-ppp/elixir/18-concurrency-system.md +466 -0
  65. package/lib/assets/docs/article/functional-desgin-ppp/elixir/19-wator-simulation.md +523 -0
  66. package/lib/assets/docs/article/functional-desgin-ppp/elixir/20-pattern-interactions.md +287 -0
  67. package/lib/assets/docs/article/functional-desgin-ppp/elixir/21-best-practices.md +340 -0
  68. package/lib/assets/docs/article/functional-desgin-ppp/elixir/22-oo-to-fp-migration.md +395 -0
  69. package/lib/assets/docs/article/functional-desgin-ppp/elixir/index.md +204 -0
  70. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/01-immutability-and-data-transformation.md +382 -0
  71. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/02-function-composition.md +452 -0
  72. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/03-polymorphism.md +495 -0
  73. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/04-data-validation.md +416 -0
  74. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/05-property-based-testing.md +382 -0
  75. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/06-tdd-functional.md +687 -0
  76. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/07-composite-pattern.md +442 -0
  77. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/08-decorator-pattern.md +479 -0
  78. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/09-adapter-pattern.md +479 -0
  79. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/10-strategy-pattern.md +427 -0
  80. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/11-command-pattern.md +428 -0
  81. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/12-visitor-pattern.md +339 -0
  82. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/13-abstract-factory-pattern.md +309 -0
  83. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/14-abstract-server-pattern.md +596 -0
  84. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/15-gossiping-bus-drivers.md +353 -0
  85. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/16-payroll-system.md +350 -0
  86. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/17-video-rental-system.md +412 -0
  87. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/18-concurrency-system.md +367 -0
  88. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/19-wator-simulation.md +401 -0
  89. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/20-pattern-interactions.md +291 -0
  90. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/21-best-practices.md +320 -0
  91. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/22-oo-to-fp-migration.md +322 -0
  92. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/index.md +230 -0
  93. package/lib/assets/docs/article/functional-desgin-ppp/haskell/01-immutability-and-data-transformation.md +298 -0
  94. package/lib/assets/docs/article/functional-desgin-ppp/haskell/02-function-composition.md +304 -0
  95. package/lib/assets/docs/article/functional-desgin-ppp/haskell/03-polymorphism.md +362 -0
  96. package/lib/assets/docs/article/functional-desgin-ppp/haskell/04-data-validation.md +257 -0
  97. package/lib/assets/docs/article/functional-desgin-ppp/haskell/05-property-based-testing.md +254 -0
  98. package/lib/assets/docs/article/functional-desgin-ppp/haskell/06-tdd-functional.md +283 -0
  99. package/lib/assets/docs/article/functional-desgin-ppp/haskell/07-composite-pattern.md +395 -0
  100. package/lib/assets/docs/article/functional-desgin-ppp/haskell/08-decorator-pattern.md +319 -0
  101. package/lib/assets/docs/article/functional-desgin-ppp/haskell/09-adapter-pattern.md +382 -0
  102. package/lib/assets/docs/article/functional-desgin-ppp/haskell/10-strategy-pattern.md +287 -0
  103. package/lib/assets/docs/article/functional-desgin-ppp/haskell/11-command-pattern.md +303 -0
  104. package/lib/assets/docs/article/functional-desgin-ppp/haskell/12-visitor-pattern.md +326 -0
  105. package/lib/assets/docs/article/functional-desgin-ppp/haskell/13-abstract-factory-pattern.md +332 -0
  106. package/lib/assets/docs/article/functional-desgin-ppp/haskell/14-abstract-server-pattern.md +379 -0
  107. package/lib/assets/docs/article/functional-desgin-ppp/haskell/15-gossiping-bus-drivers.md +175 -0
  108. package/lib/assets/docs/article/functional-desgin-ppp/haskell/16-payroll-system.md +219 -0
  109. package/lib/assets/docs/article/functional-desgin-ppp/haskell/17-video-rental-system.md +244 -0
  110. package/lib/assets/docs/article/functional-desgin-ppp/haskell/18-concurrency-system.md +363 -0
  111. package/lib/assets/docs/article/functional-desgin-ppp/haskell/19-wator-simulation.md +438 -0
  112. package/lib/assets/docs/article/functional-desgin-ppp/haskell/20-pattern-interactions.md +323 -0
  113. package/lib/assets/docs/article/functional-desgin-ppp/haskell/21-best-practices.md +403 -0
  114. package/lib/assets/docs/article/functional-desgin-ppp/haskell/22-oo-to-fp-migration.md +469 -0
  115. package/lib/assets/docs/article/functional-desgin-ppp/haskell/index.md +174 -0
  116. package/lib/assets/docs/article/functional-desgin-ppp/index.md +90 -0
  117. package/lib/assets/docs/article/functional-desgin-ppp/rust/01-immutability-and-data-transformation.md +448 -0
  118. package/lib/assets/docs/article/functional-desgin-ppp/rust/02-function-composition.md +463 -0
  119. package/lib/assets/docs/article/functional-desgin-ppp/rust/03-polymorphism.md +425 -0
  120. package/lib/assets/docs/article/functional-desgin-ppp/rust/04-data-validation.md +273 -0
  121. package/lib/assets/docs/article/functional-desgin-ppp/rust/05-property-based-testing.md +247 -0
  122. package/lib/assets/docs/article/functional-desgin-ppp/rust/06-tdd-and-functional.md +841 -0
  123. package/lib/assets/docs/article/functional-desgin-ppp/rust/07-composite-pattern.md +384 -0
  124. package/lib/assets/docs/article/functional-desgin-ppp/rust/08-decorator-pattern.md +383 -0
  125. package/lib/assets/docs/article/functional-desgin-ppp/rust/09-adapter-pattern.md +339 -0
  126. package/lib/assets/docs/article/functional-desgin-ppp/rust/10-strategy-pattern.md +331 -0
  127. package/lib/assets/docs/article/functional-desgin-ppp/rust/11-command-pattern.md +356 -0
  128. package/lib/assets/docs/article/functional-desgin-ppp/rust/12-visitor-pattern.md +379 -0
  129. package/lib/assets/docs/article/functional-desgin-ppp/rust/13-abstract-factory-pattern.md +361 -0
  130. package/lib/assets/docs/article/functional-desgin-ppp/rust/14-abstract-server-pattern.md +392 -0
  131. package/lib/assets/docs/article/functional-desgin-ppp/rust/15-gossiping-bus-drivers.md +300 -0
  132. package/lib/assets/docs/article/functional-desgin-ppp/rust/16-payroll-system.md +297 -0
  133. package/lib/assets/docs/article/functional-desgin-ppp/rust/17-video-rental-system.md +304 -0
  134. package/lib/assets/docs/article/functional-desgin-ppp/rust/18-concurrency-system.md +315 -0
  135. package/lib/assets/docs/article/functional-desgin-ppp/rust/19-wator-simulation.md +311 -0
  136. package/lib/assets/docs/article/functional-desgin-ppp/rust/20-pattern-interactions.md +304 -0
  137. package/lib/assets/docs/article/functional-desgin-ppp/rust/21-best-practices.md +336 -0
  138. package/lib/assets/docs/article/functional-desgin-ppp/rust/22-oo-to-fp-migration.md +349 -0
  139. package/lib/assets/docs/article/functional-desgin-ppp/rust/index.md +199 -0
  140. package/lib/assets/docs/article/functional-desgin-ppp/scala/01-immutability-and-data-transformation.md +326 -0
  141. package/lib/assets/docs/article/functional-desgin-ppp/scala/02-function-composition.md +348 -0
  142. package/lib/assets/docs/article/functional-desgin-ppp/scala/03-polymorphism.md +357 -0
  143. package/lib/assets/docs/article/functional-desgin-ppp/scala/04-data-validation.md +364 -0
  144. package/lib/assets/docs/article/functional-desgin-ppp/scala/05-property-based-testing.md +515 -0
  145. package/lib/assets/docs/article/functional-desgin-ppp/scala/06-tdd-functional.md +557 -0
  146. package/lib/assets/docs/article/functional-desgin-ppp/scala/07-composite-pattern.md +363 -0
  147. package/lib/assets/docs/article/functional-desgin-ppp/scala/08-decorator-pattern.md +327 -0
  148. package/lib/assets/docs/article/functional-desgin-ppp/scala/09-adapter-pattern.md +517 -0
  149. package/lib/assets/docs/article/functional-desgin-ppp/scala/10-strategy-pattern.md +441 -0
  150. package/lib/assets/docs/article/functional-desgin-ppp/scala/11-command-pattern.md +407 -0
  151. package/lib/assets/docs/article/functional-desgin-ppp/scala/12-visitor-pattern.md +379 -0
  152. package/lib/assets/docs/article/functional-desgin-ppp/scala/13-abstract-factory-pattern.md +398 -0
  153. package/lib/assets/docs/article/functional-desgin-ppp/scala/14-abstract-server-pattern.md +476 -0
  154. package/lib/assets/docs/article/functional-desgin-ppp/scala/15-gossiping-bus-drivers.md +389 -0
  155. package/lib/assets/docs/article/functional-desgin-ppp/scala/16-payroll-system.md +342 -0
  156. package/lib/assets/docs/article/functional-desgin-ppp/scala/17-video-rental-system.md +324 -0
  157. package/lib/assets/docs/article/functional-desgin-ppp/scala/18-concurrency-system.md +730 -0
  158. package/lib/assets/docs/article/functional-desgin-ppp/scala/19-wator-simulation.md +624 -0
  159. package/lib/assets/docs/article/functional-desgin-ppp/scala/20-pattern-interactions.md +512 -0
  160. package/lib/assets/docs/article/functional-desgin-ppp/scala/21-best-practices.md +427 -0
  161. package/lib/assets/docs/article/functional-desgin-ppp/scala/22-oo-to-fp-migration.md +682 -0
  162. package/lib/assets/docs/article/functional-desgin-ppp/scala/index.md +199 -0
  163. package/lib/assets/docs/article/getting-start-tdd/clojure/01-todo-list-and-first-test.md +166 -0
  164. package/lib/assets/docs/article/getting-start-tdd/clojure/02-fake-it-and-triangulation.md +162 -0
  165. package/lib/assets/docs/article/getting-start-tdd/clojure/03-obvious-implementation-and-refactoring.md +135 -0
  166. package/lib/assets/docs/article/getting-start-tdd/clojure/04-version-control-and-conventional-commits.md +88 -0
  167. package/lib/assets/docs/article/getting-start-tdd/clojure/05-package-management-and-static-analysis.md +299 -0
  168. package/lib/assets/docs/article/getting-start-tdd/clojure/06-task-runner-and-ci-cd.md +241 -0
  169. package/lib/assets/docs/article/getting-start-tdd/clojure/07-protocols-and-records.md +131 -0
  170. package/lib/assets/docs/article/getting-start-tdd/clojure/08-multimethods-and-design-patterns.md +130 -0
  171. package/lib/assets/docs/article/getting-start-tdd/clojure/09-namespaces-and-module-design.md +127 -0
  172. package/lib/assets/docs/article/getting-start-tdd/clojure/10-higher-order-functions-and-composition.md +114 -0
  173. package/lib/assets/docs/article/getting-start-tdd/clojure/11-persistent-data-and-pipeline.md +138 -0
  174. package/lib/assets/docs/article/getting-start-tdd/clojure/12-error-handling-and-spec.md +161 -0
  175. package/lib/assets/docs/article/getting-start-tdd/clojure/index.md +65 -0
  176. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter01.md +232 -0
  177. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter02.md +244 -0
  178. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter03.md +202 -0
  179. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter04.md +92 -0
  180. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter05.md +256 -0
  181. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter06.md +195 -0
  182. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter07.md +214 -0
  183. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter08.md +249 -0
  184. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter09.md +174 -0
  185. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter10.md +166 -0
  186. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter11.md +192 -0
  187. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter12.md +211 -0
  188. package/lib/assets/docs/article/getting-start-tdd/csharp/index.md +83 -0
  189. package/lib/assets/docs/article/getting-start-tdd/elixir/01-todo-list-and-first-test.md +87 -0
  190. package/lib/assets/docs/article/getting-start-tdd/elixir/02-fake-it-and-triangulation.md +95 -0
  191. package/lib/assets/docs/article/getting-start-tdd/elixir/03-obvious-implementation-and-refactoring.md +109 -0
  192. package/lib/assets/docs/article/getting-start-tdd/elixir/04-version-control-and-conventional-commits.md +96 -0
  193. package/lib/assets/docs/article/getting-start-tdd/elixir/05-package-management-and-static-analysis.md +88 -0
  194. package/lib/assets/docs/article/getting-start-tdd/elixir/06-task-runner-and-ci-cd.md +71 -0
  195. package/lib/assets/docs/article/getting-start-tdd/elixir/07-structs-and-protocols.md +110 -0
  196. package/lib/assets/docs/article/getting-start-tdd/elixir/08-pattern-matching-and-guards.md +108 -0
  197. package/lib/assets/docs/article/getting-start-tdd/elixir/09-module-design-and-behaviours.md +104 -0
  198. package/lib/assets/docs/article/getting-start-tdd/elixir/10-higher-order-functions-and-pipeline.md +178 -0
  199. package/lib/assets/docs/article/getting-start-tdd/elixir/11-stream-and-lazy-evaluation.md +142 -0
  200. package/lib/assets/docs/article/getting-start-tdd/elixir/12-error-handling-and-with.md +145 -0
  201. package/lib/assets/docs/article/getting-start-tdd/elixir/index.md +35 -0
  202. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter01.md +202 -0
  203. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter02.md +246 -0
  204. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter03.md +218 -0
  205. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter04.md +179 -0
  206. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter05.md +267 -0
  207. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter06.md +190 -0
  208. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter07.md +161 -0
  209. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter08.md +175 -0
  210. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter09.md +222 -0
  211. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter10.md +189 -0
  212. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter11.md +212 -0
  213. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter12.md +215 -0
  214. package/lib/assets/docs/article/getting-start-tdd/fsharp/index.md +71 -0
  215. package/lib/assets/docs/article/getting-start-tdd/go/01-todo-list-and-first-test.md +213 -0
  216. package/lib/assets/docs/article/getting-start-tdd/go/02-fake-it-and-triangulation.md +302 -0
  217. package/lib/assets/docs/article/getting-start-tdd/go/03-obvious-implementation-and-refactoring.md +339 -0
  218. package/lib/assets/docs/article/getting-start-tdd/go/04-version-control-and-conventional-commits.md +112 -0
  219. package/lib/assets/docs/article/getting-start-tdd/go/05-package-management-and-static-analysis.md +272 -0
  220. package/lib/assets/docs/article/getting-start-tdd/go/06-task-runner-and-ci-cd.md +233 -0
  221. package/lib/assets/docs/article/getting-start-tdd/go/07-encapsulation-and-polymorphism.md +394 -0
  222. package/lib/assets/docs/article/getting-start-tdd/go/08-design-patterns.md +422 -0
  223. package/lib/assets/docs/article/getting-start-tdd/go/09-solid-principles-and-module-design.md +400 -0
  224. package/lib/assets/docs/article/getting-start-tdd/go/10-higher-order-functions-and-composition.md +226 -0
  225. package/lib/assets/docs/article/getting-start-tdd/go/11-immutable-data-and-pipeline.md +296 -0
  226. package/lib/assets/docs/article/getting-start-tdd/go/12-error-handling-and-type-safety.md +411 -0
  227. package/lib/assets/docs/article/getting-start-tdd/go/index.md +83 -0
  228. package/lib/assets/docs/article/getting-start-tdd/haskell/01-todo-list-and-first-test.md +279 -0
  229. package/lib/assets/docs/article/getting-start-tdd/haskell/02-fake-it-and-triangulation.md +337 -0
  230. package/lib/assets/docs/article/getting-start-tdd/haskell/03-obvious-implementation-and-refactoring.md +257 -0
  231. package/lib/assets/docs/article/getting-start-tdd/haskell/04-version-control-and-conventional-commits.md +182 -0
  232. package/lib/assets/docs/article/getting-start-tdd/haskell/05-package-management-and-static-analysis.md +313 -0
  233. package/lib/assets/docs/article/getting-start-tdd/haskell/06-task-runner-and-ci-cd.md +309 -0
  234. package/lib/assets/docs/article/getting-start-tdd/haskell/07-algebraic-data-types-and-type-classes.md +412 -0
  235. package/lib/assets/docs/article/getting-start-tdd/haskell/08-pattern-matching-and-guards.md +390 -0
  236. package/lib/assets/docs/article/getting-start-tdd/haskell/09-module-design-and-smart-constructors.md +461 -0
  237. package/lib/assets/docs/article/getting-start-tdd/haskell/10-higher-order-functions-and-currying.md +434 -0
  238. package/lib/assets/docs/article/getting-start-tdd/haskell/11-function-composition-and-point-free.md +392 -0
  239. package/lib/assets/docs/article/getting-start-tdd/haskell/12-monad-and-error-handling.md +631 -0
  240. package/lib/assets/docs/article/getting-start-tdd/haskell/index.md +49 -0
  241. package/lib/assets/docs/article/getting-start-tdd/index.md +93 -0
  242. package/lib/assets/docs/article/getting-start-tdd/integration/01-language-overview.md +375 -0
  243. package/lib/assets/docs/article/getting-start-tdd/integration/02-test-framework-comparison.md +349 -0
  244. package/lib/assets/docs/article/getting-start-tdd/integration/03-tdd-pattern-comparison.md +445 -0
  245. package/lib/assets/docs/article/getting-start-tdd/integration/04-type-system-comparison.md +405 -0
  246. package/lib/assets/docs/article/getting-start-tdd/integration/05-dev-environment-comparison.md +330 -0
  247. package/lib/assets/docs/article/getting-start-tdd/integration/06-learning-roadmap.md +274 -0
  248. package/lib/assets/docs/article/getting-start-tdd/integration/index.md +69 -0
  249. package/lib/assets/docs/article/getting-start-tdd/java/01-todo-list-and-first-test.md +234 -0
  250. package/lib/assets/docs/article/getting-start-tdd/java/02-fake-it-and-triangulation.md +261 -0
  251. package/lib/assets/docs/article/getting-start-tdd/java/03-obvious-implementation-and-refactoring.md +185 -0
  252. package/lib/assets/docs/article/getting-start-tdd/java/04-version-control-and-conventional-commits.md +115 -0
  253. package/lib/assets/docs/article/getting-start-tdd/java/05-package-management-and-static-analysis.md +382 -0
  254. package/lib/assets/docs/article/getting-start-tdd/java/06-task-runner-and-ci-cd.md +272 -0
  255. package/lib/assets/docs/article/getting-start-tdd/java/07-encapsulation-and-polymorphism.md +626 -0
  256. package/lib/assets/docs/article/getting-start-tdd/java/08-design-patterns.md +393 -0
  257. package/lib/assets/docs/article/getting-start-tdd/java/09-solid-principles-and-module-design.md +310 -0
  258. package/lib/assets/docs/article/getting-start-tdd/java/10-higher-order-functions-and-composition.md +188 -0
  259. package/lib/assets/docs/article/getting-start-tdd/java/11-immutable-data-and-pipeline.md +167 -0
  260. package/lib/assets/docs/article/getting-start-tdd/java/12-error-handling-and-type-safety.md +205 -0
  261. package/lib/assets/docs/article/getting-start-tdd/java/index.md +61 -0
  262. package/lib/assets/docs/article/getting-start-tdd/node/01-todo-list-and-first-test.md +244 -0
  263. package/lib/assets/docs/article/getting-start-tdd/node/02-fake-it-and-triangulation.md +262 -0
  264. package/lib/assets/docs/article/getting-start-tdd/node/03-obvious-implementation-and-refactoring.md +169 -0
  265. package/lib/assets/docs/article/getting-start-tdd/node/04-version-control-and-conventional-commits.md +112 -0
  266. package/lib/assets/docs/article/getting-start-tdd/node/05-package-management-and-static-analysis.md +314 -0
  267. package/lib/assets/docs/article/getting-start-tdd/node/06-task-runner-and-ci-cd.md +235 -0
  268. package/lib/assets/docs/article/getting-start-tdd/node/07-encapsulation-and-polymorphism.md +327 -0
  269. package/lib/assets/docs/article/getting-start-tdd/node/08-design-patterns.md +322 -0
  270. package/lib/assets/docs/article/getting-start-tdd/node/09-solid-principles-and-module-design.md +285 -0
  271. package/lib/assets/docs/article/getting-start-tdd/node/10-higher-order-functions-and-composition.md +199 -0
  272. package/lib/assets/docs/article/getting-start-tdd/node/11-immutable-data-and-pipeline.md +207 -0
  273. package/lib/assets/docs/article/getting-start-tdd/node/12-error-handling-and-type-safety.md +295 -0
  274. package/lib/assets/docs/article/getting-start-tdd/node/index.md +56 -0
  275. package/lib/assets/docs/article/getting-start-tdd/php/01-todo-list-and-first-test.md +259 -0
  276. package/lib/assets/docs/article/getting-start-tdd/php/02-fake-it-and-triangulation.md +200 -0
  277. package/lib/assets/docs/article/getting-start-tdd/php/03-obvious-implementation-and-refactoring.md +248 -0
  278. package/lib/assets/docs/article/getting-start-tdd/php/04-version-control-and-conventional-commits.md +141 -0
  279. package/lib/assets/docs/article/getting-start-tdd/php/05-package-management-and-static-analysis.md +410 -0
  280. package/lib/assets/docs/article/getting-start-tdd/php/06-task-runner-and-ci-cd.md +321 -0
  281. package/lib/assets/docs/article/getting-start-tdd/php/07-encapsulation-and-polymorphism.md +372 -0
  282. package/lib/assets/docs/article/getting-start-tdd/php/08-design-patterns.md +453 -0
  283. package/lib/assets/docs/article/getting-start-tdd/php/09-solid-principles-and-module-design.md +460 -0
  284. package/lib/assets/docs/article/getting-start-tdd/php/10-higher-order-functions-and-composition.md +182 -0
  285. package/lib/assets/docs/article/getting-start-tdd/php/11-immutable-data-and-pipeline.md +266 -0
  286. package/lib/assets/docs/article/getting-start-tdd/php/12-error-handling-and-type-safety.md +308 -0
  287. package/lib/assets/docs/article/getting-start-tdd/php/index.md +84 -0
  288. package/lib/assets/docs/article/getting-start-tdd/python/01-todo-list-and-first-test.md +201 -0
  289. package/lib/assets/docs/article/getting-start-tdd/python/02-fake-it-and-triangulation.md +247 -0
  290. package/lib/assets/docs/article/getting-start-tdd/python/03-obvious-implementation-and-refactoring.md +199 -0
  291. package/lib/assets/docs/article/getting-start-tdd/python/04-version-control-and-conventional-commits.md +87 -0
  292. package/lib/assets/docs/article/getting-start-tdd/python/05-package-management-and-static-analysis.md +274 -0
  293. package/lib/assets/docs/article/getting-start-tdd/python/06-task-runner-and-ci-cd.md +190 -0
  294. package/lib/assets/docs/article/getting-start-tdd/python/07-encapsulation-and-polymorphism.md +208 -0
  295. package/lib/assets/docs/article/getting-start-tdd/python/08-design-patterns.md +172 -0
  296. package/lib/assets/docs/article/getting-start-tdd/python/09-solid-principles-and-module-design.md +130 -0
  297. package/lib/assets/docs/article/getting-start-tdd/python/10-higher-order-functions-and-composition.md +122 -0
  298. package/lib/assets/docs/article/getting-start-tdd/python/11-immutable-data-and-pipeline.md +116 -0
  299. package/lib/assets/docs/article/getting-start-tdd/python/12-error-handling-and-type-safety.md +126 -0
  300. package/lib/assets/docs/article/getting-start-tdd/python/index.md +55 -0
  301. package/lib/assets/docs/article/getting-start-tdd/ruby/01-todo-list-and-first-test.md +231 -0
  302. package/lib/assets/docs/article/getting-start-tdd/ruby/02-fake-it-and-triangulation.md +238 -0
  303. package/lib/assets/docs/article/getting-start-tdd/ruby/03-obvious-implementation-and-refactoring.md +228 -0
  304. package/lib/assets/docs/article/getting-start-tdd/ruby/04-version-control-and-conventional-commits.md +112 -0
  305. package/lib/assets/docs/article/getting-start-tdd/ruby/05-package-management-and-static-analysis.md +287 -0
  306. package/lib/assets/docs/article/getting-start-tdd/ruby/06-task-runner-and-ci-cd.md +248 -0
  307. package/lib/assets/docs/article/getting-start-tdd/ruby/07-encapsulation-and-polymorphism.md +279 -0
  308. package/lib/assets/docs/article/getting-start-tdd/ruby/08-design-patterns.md +329 -0
  309. package/lib/assets/docs/article/getting-start-tdd/ruby/09-solid-principles-and-module-design.md +196 -0
  310. package/lib/assets/docs/article/getting-start-tdd/ruby/10-higher-order-functions-and-composition.md +175 -0
  311. package/lib/assets/docs/article/getting-start-tdd/ruby/11-immutable-data-and-pipeline.md +233 -0
  312. package/lib/assets/docs/article/getting-start-tdd/ruby/12-error-handling-and-type-safety.md +398 -0
  313. package/lib/assets/docs/article/getting-start-tdd/ruby/index.md +83 -0
  314. package/lib/assets/docs/article/getting-start-tdd/rust/01-todo-list-and-first-test.md +211 -0
  315. package/lib/assets/docs/article/getting-start-tdd/rust/02-fake-it-and-triangulation.md +264 -0
  316. package/lib/assets/docs/article/getting-start-tdd/rust/03-obvious-implementation-and-refactoring.md +233 -0
  317. package/lib/assets/docs/article/getting-start-tdd/rust/04-version-control-and-conventional-commits.md +92 -0
  318. package/lib/assets/docs/article/getting-start-tdd/rust/05-package-management-and-static-analysis.md +212 -0
  319. package/lib/assets/docs/article/getting-start-tdd/rust/06-task-runner-and-ci-cd.md +164 -0
  320. package/lib/assets/docs/article/getting-start-tdd/rust/07-encapsulation-and-polymorphism.md +142 -0
  321. package/lib/assets/docs/article/getting-start-tdd/rust/08-design-patterns.md +145 -0
  322. package/lib/assets/docs/article/getting-start-tdd/rust/09-solid-principles-and-module-design.md +110 -0
  323. package/lib/assets/docs/article/getting-start-tdd/rust/10-higher-order-functions-and-composition.md +94 -0
  324. package/lib/assets/docs/article/getting-start-tdd/rust/11-immutable-data-and-pipeline.md +105 -0
  325. package/lib/assets/docs/article/getting-start-tdd/rust/12-error-handling-and-type-safety.md +112 -0
  326. package/lib/assets/docs/article/getting-start-tdd/rust/index.md +83 -0
  327. package/lib/assets/docs/article/getting-start-tdd/scala/01-todo-list-and-first-test.md +111 -0
  328. package/lib/assets/docs/article/getting-start-tdd/scala/02-fake-it-and-triangulation.md +107 -0
  329. package/lib/assets/docs/article/getting-start-tdd/scala/03-obvious-implementation-and-refactoring.md +99 -0
  330. package/lib/assets/docs/article/getting-start-tdd/scala/04-version-control-and-conventional-commits.md +123 -0
  331. package/lib/assets/docs/article/getting-start-tdd/scala/05-package-management-and-static-analysis.md +196 -0
  332. package/lib/assets/docs/article/getting-start-tdd/scala/06-task-runner-and-ci-cd.md +186 -0
  333. package/lib/assets/docs/article/getting-start-tdd/scala/07-case-classes-and-traits.md +139 -0
  334. package/lib/assets/docs/article/getting-start-tdd/scala/08-pattern-matching-and-sealed-traits.md +106 -0
  335. package/lib/assets/docs/article/getting-start-tdd/scala/09-packages-and-module-design.md +75 -0
  336. package/lib/assets/docs/article/getting-start-tdd/scala/10-higher-order-functions-and-composition.md +104 -0
  337. package/lib/assets/docs/article/getting-start-tdd/scala/11-collections-and-lazy-evaluation.md +94 -0
  338. package/lib/assets/docs/article/getting-start-tdd/scala/12-error-handling-and-type-safety.md +92 -0
  339. package/lib/assets/docs/article/getting-start-tdd/scala/index.md +65 -0
  340. package/lib/assets/docs/article/grokking-concurrency/all/index.md +404 -0
  341. package/lib/assets/docs/article/grokking-concurrency/all/part-1-ch02-sequential.md +554 -0
  342. package/lib/assets/docs/article/grokking-concurrency/all/part-2-ch04-05-threads.md +469 -0
  343. package/lib/assets/docs/article/grokking-concurrency/all/part-3-ch06-multitasking.md +520 -0
  344. package/lib/assets/docs/article/grokking-concurrency/all/part-4-ch07-parallel-patterns.md +420 -0
  345. package/lib/assets/docs/article/grokking-concurrency/all/part-5-ch08-09-synchronization.md +510 -0
  346. package/lib/assets/docs/article/grokking-concurrency/all/part-6-ch10-11-nonblocking-io.md +435 -0
  347. package/lib/assets/docs/article/grokking-concurrency/all/part-7-ch12-async.md +465 -0
  348. package/lib/assets/docs/article/grokking-concurrency/all/part-8-ch13-mapreduce.md +377 -0
  349. package/lib/assets/docs/article/grokking-concurrency/clojure/index.md +116 -0
  350. package/lib/assets/docs/article/grokking-concurrency/clojure/part-1.md +108 -0
  351. package/lib/assets/docs/article/grokking-concurrency/clojure/part-2.md +101 -0
  352. package/lib/assets/docs/article/grokking-concurrency/clojure/part-3.md +122 -0
  353. package/lib/assets/docs/article/grokking-concurrency/clojure/part-4.md +123 -0
  354. package/lib/assets/docs/article/grokking-concurrency/clojure/part-5.md +118 -0
  355. package/lib/assets/docs/article/grokking-concurrency/clojure/part-6.md +89 -0
  356. package/lib/assets/docs/article/grokking-concurrency/clojure/part-7.md +100 -0
  357. package/lib/assets/docs/article/grokking-concurrency/clojure/part-8.md +120 -0
  358. package/lib/assets/docs/article/grokking-concurrency/csharp/index.md +101 -0
  359. package/lib/assets/docs/article/grokking-concurrency/csharp/part-1.md +97 -0
  360. package/lib/assets/docs/article/grokking-concurrency/csharp/part-2.md +123 -0
  361. package/lib/assets/docs/article/grokking-concurrency/csharp/part-3.md +101 -0
  362. package/lib/assets/docs/article/grokking-concurrency/csharp/part-4.md +112 -0
  363. package/lib/assets/docs/article/grokking-concurrency/csharp/part-5.md +99 -0
  364. package/lib/assets/docs/article/grokking-concurrency/csharp/part-6.md +61 -0
  365. package/lib/assets/docs/article/grokking-concurrency/csharp/part-7.md +84 -0
  366. package/lib/assets/docs/article/grokking-concurrency/csharp/part-8.md +92 -0
  367. package/lib/assets/docs/article/grokking-concurrency/fsharp/index.md +65 -0
  368. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-1.md +80 -0
  369. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-2.md +103 -0
  370. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-3.md +94 -0
  371. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-4.md +110 -0
  372. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-5.md +104 -0
  373. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-6.md +93 -0
  374. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-7.md +121 -0
  375. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-8.md +107 -0
  376. package/lib/assets/docs/article/grokking-concurrency/haskell/index.md +248 -0
  377. package/lib/assets/docs/article/grokking-concurrency/haskell/part-1.md +96 -0
  378. package/lib/assets/docs/article/grokking-concurrency/haskell/part-2.md +96 -0
  379. package/lib/assets/docs/article/grokking-concurrency/haskell/part-3.md +91 -0
  380. package/lib/assets/docs/article/grokking-concurrency/haskell/part-4.md +106 -0
  381. package/lib/assets/docs/article/grokking-concurrency/haskell/part-5.md +99 -0
  382. package/lib/assets/docs/article/grokking-concurrency/haskell/part-6.md +95 -0
  383. package/lib/assets/docs/article/grokking-concurrency/haskell/part-7.md +111 -0
  384. package/lib/assets/docs/article/grokking-concurrency/haskell/part-8.md +118 -0
  385. package/lib/assets/docs/article/grokking-concurrency/index.md +66 -0
  386. package/lib/assets/docs/article/grokking-concurrency/java/index.md +102 -0
  387. package/lib/assets/docs/article/grokking-concurrency/java/part-1.md +308 -0
  388. package/lib/assets/docs/article/grokking-concurrency/java/part-2.md +334 -0
  389. package/lib/assets/docs/article/grokking-concurrency/java/part-3.md +221 -0
  390. package/lib/assets/docs/article/grokking-concurrency/java/part-4.md +213 -0
  391. package/lib/assets/docs/article/grokking-concurrency/java/part-5.md +112 -0
  392. package/lib/assets/docs/article/grokking-concurrency/java/part-6.md +69 -0
  393. package/lib/assets/docs/article/grokking-concurrency/java/part-7.md +101 -0
  394. package/lib/assets/docs/article/grokking-concurrency/java/part-8.md +101 -0
  395. package/lib/assets/docs/article/grokking-concurrency/python/index.md +313 -0
  396. package/lib/assets/docs/article/grokking-concurrency/python/part-1.md +239 -0
  397. package/lib/assets/docs/article/grokking-concurrency/python/part-2.md +418 -0
  398. package/lib/assets/docs/article/grokking-concurrency/python/part-3.md +227 -0
  399. package/lib/assets/docs/article/grokking-concurrency/python/part-4.md +299 -0
  400. package/lib/assets/docs/article/grokking-concurrency/python/part-5.md +315 -0
  401. package/lib/assets/docs/article/grokking-concurrency/python/part-6.md +297 -0
  402. package/lib/assets/docs/article/grokking-concurrency/python/part-7.md +314 -0
  403. package/lib/assets/docs/article/grokking-concurrency/python/part-8.md +360 -0
  404. package/lib/assets/docs/article/grokking-concurrency/rust/index.md +270 -0
  405. package/lib/assets/docs/article/grokking-concurrency/rust/part-1.md +108 -0
  406. package/lib/assets/docs/article/grokking-concurrency/rust/part-2.md +120 -0
  407. package/lib/assets/docs/article/grokking-concurrency/rust/part-3.md +126 -0
  408. package/lib/assets/docs/article/grokking-concurrency/rust/part-4.md +175 -0
  409. package/lib/assets/docs/article/grokking-concurrency/rust/part-5.md +158 -0
  410. package/lib/assets/docs/article/grokking-concurrency/rust/part-6.md +94 -0
  411. package/lib/assets/docs/article/grokking-concurrency/rust/part-7.md +133 -0
  412. package/lib/assets/docs/article/grokking-concurrency/rust/part-8.md +155 -0
  413. package/lib/assets/docs/article/grokking-concurrency/scala/index.md +69 -0
  414. package/lib/assets/docs/article/grokking-concurrency/scala/part-1.md +78 -0
  415. package/lib/assets/docs/article/grokking-concurrency/scala/part-2.md +112 -0
  416. package/lib/assets/docs/article/grokking-concurrency/scala/part-3.md +93 -0
  417. package/lib/assets/docs/article/grokking-concurrency/scala/part-4.md +110 -0
  418. package/lib/assets/docs/article/grokking-concurrency/scala/part-5.md +119 -0
  419. package/lib/assets/docs/article/grokking-concurrency/scala/part-6.md +83 -0
  420. package/lib/assets/docs/article/grokking-concurrency/scala/part-7.md +131 -0
  421. package/lib/assets/docs/article/grokking-concurrency/scala/part-8.md +129 -0
  422. package/lib/assets/docs/article/grokkingfp/all/index.md +368 -0
  423. package/lib/assets/docs/article/grokkingfp/all/part-1-ch01-fp-introduction.md +530 -0
  424. package/lib/assets/docs/article/grokkingfp/all/part-1-ch02-pure-functions.md +923 -0
  425. package/lib/assets/docs/article/grokkingfp/all/part-2-ch03-immutable-data.md +1122 -0
  426. package/lib/assets/docs/article/grokkingfp/all/part-2-ch04-higher-order-functions.md +1104 -0
  427. package/lib/assets/docs/article/grokkingfp/all/part-2-ch05-flatmap.md +1026 -0
  428. package/lib/assets/docs/article/grokkingfp/all/part-3-ch06-option.md +777 -0
  429. package/lib/assets/docs/article/grokkingfp/all/part-3-ch07-either-adt.md +871 -0
  430. package/lib/assets/docs/article/grokkingfp/all/part-4-ch08-io-monad.md +972 -0
  431. package/lib/assets/docs/article/grokkingfp/all/part-4-ch09-streams.md +926 -0
  432. package/lib/assets/docs/article/grokkingfp/all/part-5-ch10-concurrency.md +870 -0
  433. package/lib/assets/docs/article/grokkingfp/all/part-6-ch11-application.md +715 -0
  434. package/lib/assets/docs/article/grokkingfp/all/part-6-ch12-testing.md +626 -0
  435. package/lib/assets/docs/article/grokkingfp/all/writing-plan.md +696 -0
  436. package/lib/assets/docs/article/grokkingfp/clojure/index.md +276 -0
  437. package/lib/assets/docs/article/grokkingfp/clojure/part-1.md +667 -0
  438. package/lib/assets/docs/article/grokkingfp/clojure/part-2.md +643 -0
  439. package/lib/assets/docs/article/grokkingfp/clojure/part-3.md +620 -0
  440. package/lib/assets/docs/article/grokkingfp/clojure/part-4.md +697 -0
  441. package/lib/assets/docs/article/grokkingfp/clojure/part-5.md +751 -0
  442. package/lib/assets/docs/article/grokkingfp/clojure/part-6.md +721 -0
  443. package/lib/assets/docs/article/grokkingfp/csharp/index.md +246 -0
  444. package/lib/assets/docs/article/grokkingfp/csharp/part-1.md +811 -0
  445. package/lib/assets/docs/article/grokkingfp/csharp/part-2.md +971 -0
  446. package/lib/assets/docs/article/grokkingfp/csharp/part-3.md +981 -0
  447. package/lib/assets/docs/article/grokkingfp/csharp/part-4.md +949 -0
  448. package/lib/assets/docs/article/grokkingfp/csharp/part-5.md +947 -0
  449. package/lib/assets/docs/article/grokkingfp/csharp/part-6.md +739 -0
  450. package/lib/assets/docs/article/grokkingfp/elixir/index.md +203 -0
  451. package/lib/assets/docs/article/grokkingfp/elixir/part-1.md +710 -0
  452. package/lib/assets/docs/article/grokkingfp/elixir/part-2.md +838 -0
  453. package/lib/assets/docs/article/grokkingfp/elixir/part-3.md +985 -0
  454. package/lib/assets/docs/article/grokkingfp/elixir/part-4.md +974 -0
  455. package/lib/assets/docs/article/grokkingfp/elixir/part-5.md +1284 -0
  456. package/lib/assets/docs/article/grokkingfp/elixir/part-6.md +1047 -0
  457. package/lib/assets/docs/article/grokkingfp/fsharp/index.md +210 -0
  458. package/lib/assets/docs/article/grokkingfp/fsharp/part-1.md +714 -0
  459. package/lib/assets/docs/article/grokkingfp/fsharp/part-2.md +961 -0
  460. package/lib/assets/docs/article/grokkingfp/fsharp/part-3.md +972 -0
  461. package/lib/assets/docs/article/grokkingfp/fsharp/part-4.md +832 -0
  462. package/lib/assets/docs/article/grokkingfp/fsharp/part-5.md +911 -0
  463. package/lib/assets/docs/article/grokkingfp/fsharp/part-6.md +920 -0
  464. package/lib/assets/docs/article/grokkingfp/haskell/index.md +234 -0
  465. package/lib/assets/docs/article/grokkingfp/haskell/part-1.md +591 -0
  466. package/lib/assets/docs/article/grokkingfp/haskell/part-2.md +866 -0
  467. package/lib/assets/docs/article/grokkingfp/haskell/part-3.md +915 -0
  468. package/lib/assets/docs/article/grokkingfp/haskell/part-4.md +876 -0
  469. package/lib/assets/docs/article/grokkingfp/haskell/part-5.md +845 -0
  470. package/lib/assets/docs/article/grokkingfp/haskell/part-6.md +842 -0
  471. package/lib/assets/docs/article/grokkingfp/index.md +143 -0
  472. package/lib/assets/docs/article/grokkingfp/java/index.md +211 -0
  473. package/lib/assets/docs/article/grokkingfp/java/part-1.md +646 -0
  474. package/lib/assets/docs/article/grokkingfp/java/part-2.md +667 -0
  475. package/lib/assets/docs/article/grokkingfp/java/part-3.md +672 -0
  476. package/lib/assets/docs/article/grokkingfp/java/part-4.md +771 -0
  477. package/lib/assets/docs/article/grokkingfp/java/part-5.md +959 -0
  478. package/lib/assets/docs/article/grokkingfp/java/part-6.md +1324 -0
  479. package/lib/assets/docs/article/grokkingfp/python/index.md +258 -0
  480. package/lib/assets/docs/article/grokkingfp/python/part-1.md +437 -0
  481. package/lib/assets/docs/article/grokkingfp/python/part-2.md +958 -0
  482. package/lib/assets/docs/article/grokkingfp/python/part-3.md +1004 -0
  483. package/lib/assets/docs/article/grokkingfp/python/part-4.md +765 -0
  484. package/lib/assets/docs/article/grokkingfp/python/part-5.md +747 -0
  485. package/lib/assets/docs/article/grokkingfp/python/part-6.md +861 -0
  486. package/lib/assets/docs/article/grokkingfp/ruby/index.md +330 -0
  487. package/lib/assets/docs/article/grokkingfp/ruby/part-1.md +753 -0
  488. package/lib/assets/docs/article/grokkingfp/ruby/part-2.md +938 -0
  489. package/lib/assets/docs/article/grokkingfp/ruby/part-3.md +946 -0
  490. package/lib/assets/docs/article/grokkingfp/ruby/part-4.md +921 -0
  491. package/lib/assets/docs/article/grokkingfp/ruby/part-5.md +908 -0
  492. package/lib/assets/docs/article/grokkingfp/ruby/part-6.md +1410 -0
  493. package/lib/assets/docs/article/grokkingfp/rust/index.md +242 -0
  494. package/lib/assets/docs/article/grokkingfp/rust/part-1.md +634 -0
  495. package/lib/assets/docs/article/grokkingfp/rust/part-2.md +1060 -0
  496. package/lib/assets/docs/article/grokkingfp/rust/part-3.md +994 -0
  497. package/lib/assets/docs/article/grokkingfp/rust/part-4.md +571 -0
  498. package/lib/assets/docs/article/grokkingfp/rust/part-5.md +705 -0
  499. package/lib/assets/docs/article/grokkingfp/rust/part-6.md +508 -0
  500. package/lib/assets/docs/article/grokkingfp/scala/index.md +171 -0
  501. package/lib/assets/docs/article/grokkingfp/scala/part-1.md +541 -0
  502. package/lib/assets/docs/article/grokkingfp/scala/part-2.md +946 -0
  503. package/lib/assets/docs/article/grokkingfp/scala/part-3.md +917 -0
  504. package/lib/assets/docs/article/grokkingfp/scala/part-4.md +742 -0
  505. package/lib/assets/docs/article/grokkingfp/scala/part-5.md +722 -0
  506. package/lib/assets/docs/article/grokkingfp/scala/part-6.md +865 -0
  507. package/lib/assets/docs/article/grokkingfp/typescript/index.md +273 -0
  508. package/lib/assets/docs/article/grokkingfp/typescript/part-1.md +559 -0
  509. package/lib/assets/docs/article/grokkingfp/typescript/part-2.md +1129 -0
  510. package/lib/assets/docs/article/grokkingfp/typescript/part-3.md +842 -0
  511. package/lib/assets/docs/article/grokkingfp/typescript/part-4.md +1085 -0
  512. package/lib/assets/docs/article/grokkingfp/typescript/part-5.md +717 -0
  513. package/lib/assets/docs/article/grokkingfp/typescript/part-6.md +980 -0
  514. package/lib/assets/docs/article/index.md +36 -0
  515. package/lib/assets/docs/design/index.md +39 -27
  516. package/lib/assets/docs/development/index.md +11 -1
  517. package/lib/assets/docs/index.md +33 -106
  518. package/lib/assets/docs/operation/index.md +16 -6
  519. package/lib/assets/docs/reference/index.md +5 -4
  520. package/lib/assets/docs/requirements/index.md +13 -6
  521. package/lib/assets/docs/strategy/index.md +11 -4
  522. package/lib/assets/docs/template/index.md +9 -5
  523. package/lib/assets/mkdocs.yml +29 -17
  524. package/package.json +1 -1
@@ -0,0 +1,342 @@
1
+ # 第16章: 給与計算システム
2
+
3
+ ## はじめに
4
+
5
+ 本章では、給与計算システムを題材に、関数型プログラミングにおけるドメインモデリングと多態性の実現を学びます。
6
+
7
+ この問題を通じて以下の概念を学びます:
8
+
9
+ - Sealed trait と case class によるドメインモデリング
10
+ - 型クラスによる給与タイプ別の計算
11
+ - 支払いスケジュールのモデリング
12
+ - イベントソーシング風の履歴管理
13
+
14
+ ## 1. ドメインモデル
15
+
16
+ ### 給与タイプ
17
+
18
+ 給与計算システムでは、以下の3種類の給与タイプをサポートします:
19
+
20
+ - **月給制(Salaried)**: 固定月給
21
+ - **時給制(Hourly)**: 労働時間に基づく給与
22
+ - **歩合制(Commissioned)**: 基本給 + 売上に応じたコミッション
23
+
24
+ ```scala
25
+ sealed trait PayClass:
26
+ def payType: String
27
+
28
+ case class Salaried(salary: Money) extends PayClass:
29
+ def payType: String = "salaried"
30
+
31
+ case class Hourly(hourlyRate: Money) extends PayClass:
32
+ def payType: String = "hourly"
33
+
34
+ case class Commissioned(basePay: Money, commissionRate: Rate) extends PayClass:
35
+ def payType: String = "commissioned"
36
+ ```
37
+
38
+ ### 支払いスケジュール
39
+
40
+ ```scala
41
+ enum Schedule:
42
+ case Monthly // 月次(月末)
43
+ case Weekly // 週次(毎週金曜日)
44
+ case Biweekly // 隔週(隔週金曜日)
45
+ ```
46
+
47
+ ### 支払い方法
48
+
49
+ ```scala
50
+ enum PaymentMethod:
51
+ case Hold // 保留
52
+ case DirectDeposit(accountNumber: String) // 口座振込
53
+ case Mail(address: String) // 小切手郵送
54
+ ```
55
+
56
+ ## 2. 従業員モデル
57
+
58
+ ```scala
59
+ case class Employee(
60
+ id: EmployeeId,
61
+ name: String,
62
+ payClass: PayClass,
63
+ schedule: Schedule,
64
+ paymentMethod: PaymentMethod,
65
+ address: Option[String] = None
66
+ )
67
+
68
+ object Employee:
69
+ def salaried(id: EmployeeId, name: String, salary: Money): Employee =
70
+ Employee(id, name, Salaried(salary), Schedule.Monthly, PaymentMethod.Hold)
71
+
72
+ def hourly(id: EmployeeId, name: String, hourlyRate: Money): Employee =
73
+ Employee(id, name, Hourly(hourlyRate), Schedule.Weekly, PaymentMethod.Hold)
74
+
75
+ def commissioned(id: EmployeeId, name: String, basePay: Money, commissionRate: Rate): Employee =
76
+ Employee(id, name, Commissioned(basePay, commissionRate), Schedule.Biweekly, PaymentMethod.Hold)
77
+ ```
78
+
79
+ ## 3. コンテキスト(タイムカード、売上)
80
+
81
+ ```scala
82
+ case class TimeCard(employeeId: EmployeeId, date: String, hours: Hours)
83
+ case class SalesReceipt(employeeId: EmployeeId, date: String, amount: Money)
84
+
85
+ case class PayrollContext(
86
+ timeCards: Map[EmployeeId, List[TimeCard]] = Map.empty.withDefaultValue(Nil),
87
+ salesReceipts: Map[EmployeeId, List[SalesReceipt]] = Map.empty.withDefaultValue(Nil)
88
+ ):
89
+ def addTimeCard(tc: TimeCard): PayrollContext = ...
90
+ def addSalesReceipt(sr: SalesReceipt): PayrollContext = ...
91
+ ```
92
+
93
+ ### 使用例
94
+
95
+ ```scala
96
+ val ctx = PayrollContext.empty
97
+ .addTimeCard(TimeCard("E002", "2024-01-15", 8))
98
+ .addTimeCard(TimeCard("E002", "2024-01-16", 10))
99
+ .addSalesReceipt(SalesReceipt("E003", "2024-01-15", BigDecimal(100000)))
100
+ ```
101
+
102
+ ## 4. 給与計算
103
+
104
+ ### 型クラスアプローチ
105
+
106
+ ```scala
107
+ trait PayCalculator[P <: PayClass]:
108
+ def calculate(payClass: P, context: PayrollContext, employeeId: EmployeeId): Money
109
+
110
+ given PayCalculator[Salaried] with
111
+ def calculate(payClass: Salaried, context: PayrollContext, employeeId: EmployeeId): Money =
112
+ payClass.salary
113
+
114
+ given PayCalculator[Hourly] with
115
+ def calculate(payClass: Hourly, context: PayrollContext, employeeId: EmployeeId): Money =
116
+ val timeCards = context.getTimeCards(employeeId)
117
+ val totalHours = timeCards.map(_.hours).sum
118
+ val regularHours = math.min(totalHours, 40.0)
119
+ val overtimeHours = math.max(0.0, totalHours - 40.0)
120
+ payClass.hourlyRate * BigDecimal(regularHours) +
121
+ payClass.hourlyRate * BigDecimal(overtimeHours) * BigDecimal(1.5)
122
+
123
+ given PayCalculator[Commissioned] with
124
+ def calculate(payClass: Commissioned, context: PayrollContext, employeeId: EmployeeId): Money =
125
+ val salesReceipts = context.getSalesReceipts(employeeId)
126
+ val totalSales = salesReceipts.map(_.amount).sum
127
+ payClass.basePay + totalSales * BigDecimal(payClass.commissionRate)
128
+ ```
129
+
130
+ ### 計算例
131
+
132
+ ```scala
133
+ // 月給制: 固定給与
134
+ val salaried = Employee.salaried("E001", "田中", BigDecimal(500000))
135
+ calculatePay(salaried, ctx) // => 500000
136
+
137
+ // 時給制: 40時間 * 1500 + 5時間 * 1500 * 1.5 = 67500
138
+ val hourly = Employee.hourly("E002", "佐藤", BigDecimal(1500))
139
+ val ctx = PayrollContext.empty.addTimeCard(TimeCard("E002", "2024-01-15", 45))
140
+ calculatePay(hourly, ctx) // => 67500
141
+
142
+ // 歩合制: 200000 + 150000 * 0.1 = 215000
143
+ val commissioned = Employee.commissioned("E003", "鈴木", BigDecimal(200000), 0.1)
144
+ val ctx = PayrollContext.empty
145
+ .addSalesReceipt(SalesReceipt("E003", "2024-01-15", BigDecimal(150000)))
146
+ calculatePay(commissioned, ctx) // => 215000
147
+ ```
148
+
149
+ ## 5. 支払いスケジュール判定
150
+
151
+ ```scala
152
+ case class PayDate(
153
+ year: Int,
154
+ month: Int,
155
+ day: Int,
156
+ dayOfWeek: DayOfWeek,
157
+ isLastDayOfMonth: Boolean,
158
+ isPayWeek: Boolean = true
159
+ )
160
+
161
+ def isPayDay(employee: Employee, date: PayDate): Boolean =
162
+ employee.schedule match
163
+ case Schedule.Monthly => date.isLastDayOfMonth
164
+ case Schedule.Weekly => date.dayOfWeek == DayOfWeek.Friday
165
+ case Schedule.Biweekly => date.dayOfWeek == DayOfWeek.Friday && date.isPayWeek
166
+ ```
167
+
168
+ ## 6. 支払い処理
169
+
170
+ ```scala
171
+ sealed trait PaymentResult:
172
+ def employeeId: EmployeeId
173
+ def amount: Money
174
+
175
+ case class HeldPayment(employeeId: EmployeeId, amount: Money) extends PaymentResult
176
+ case class DirectDepositPayment(employeeId: EmployeeId, amount: Money, accountNumber: String) extends PaymentResult
177
+ case class MailedPayment(employeeId: EmployeeId, amount: Money, address: String) extends PaymentResult
178
+
179
+ def processPayment(employee: Employee, amount: Money): PaymentResult =
180
+ employee.paymentMethod match
181
+ case PaymentMethod.Hold =>
182
+ HeldPayment(employee.id, amount)
183
+ case PaymentMethod.DirectDeposit(account) =>
184
+ DirectDepositPayment(employee.id, amount, account)
185
+ case PaymentMethod.Mail(address) =>
186
+ MailedPayment(employee.id, amount, address)
187
+ ```
188
+
189
+ ## 7. 給与支払い実行
190
+
191
+ ```scala
192
+ def runPayroll(employees: Seq[Employee], context: PayrollContext, date: PayDate): Seq[PaymentResult] =
193
+ employees
194
+ .filter(isPayDay(_, date))
195
+ .map { emp =>
196
+ val pay = calculatePay(emp, context)
197
+ processPayment(emp, pay)
198
+ }
199
+ ```
200
+
201
+ ## 8. 給与明細と控除
202
+
203
+ ### 給与明細
204
+
205
+ ```scala
206
+ case class Payslip(
207
+ employeeId: EmployeeId,
208
+ employeeName: String,
209
+ payPeriod: String,
210
+ grossPay: Money,
211
+ deductions: Map[String, Money] = Map.empty,
212
+ netPay: Money
213
+ ):
214
+ def addDeduction(name: String, amount: Money): Payslip =
215
+ val newDeductions = deductions + (name -> amount)
216
+ val newNetPay = grossPay - newDeductions.values.sum
217
+ copy(deductions = newDeductions, netPay = newNetPay)
218
+ ```
219
+
220
+ ### 控除タイプ
221
+
222
+ ```scala
223
+ sealed trait Deduction:
224
+ def name: String
225
+ def calculate(grossPay: Money): Money
226
+
227
+ case class FixedDeduction(name: String, amount: Money) extends Deduction:
228
+ def calculate(grossPay: Money): Money = amount
229
+
230
+ case class PercentageDeduction(name: String, rate: Rate) extends Deduction:
231
+ def calculate(grossPay: Money): Money = grossPay * BigDecimal(rate)
232
+ ```
233
+
234
+ ### 使用例
235
+
236
+ ```scala
237
+ val deductions = Seq(
238
+ FixedDeduction("健康保険", BigDecimal(10000)),
239
+ PercentageDeduction("所得税", 0.1)
240
+ )
241
+ val payslip = Payslip.create(emp, "2024-01", BigDecimal(500000))
242
+ val result = applyDeductions(payslip, deductions)
243
+ // grossPay: 500000, deductions: {健康保険: 10000, 所得税: 50000}, netPay: 440000
244
+ ```
245
+
246
+ ## 9. 給与計算サービス
247
+
248
+ ```scala
249
+ class PayrollService(
250
+ repository: EmployeeRepository,
251
+ deductions: Seq[Deduction] = Seq.empty
252
+ ):
253
+ def addEmployee(employee: Employee): Employee = ...
254
+ def removeEmployee(id: EmployeeId): Option[Employee] = ...
255
+ def getEmployee(id: EmployeeId): Option[Employee] = ...
256
+ def updateEmployee(id: EmployeeId, f: Employee => Employee): Option[Employee] = ...
257
+
258
+ def runPayroll(context: PayrollContext, date: PayDate, payPeriod: String): Seq[Payslip] =
259
+ val employees = repository.findAll
260
+ employees
261
+ .filter(isPayDay(_, date))
262
+ .map { emp =>
263
+ val grossPay = calculatePay(emp, context)
264
+ val payslip = Payslip.create(emp, payPeriod, grossPay)
265
+ applyDeductions(payslip, deductions)
266
+ }
267
+ ```
268
+
269
+ ## 10. イベントソーシング
270
+
271
+ ```scala
272
+ sealed trait PayrollEvent:
273
+ def timestamp: Long
274
+ def employeeId: EmployeeId
275
+
276
+ case class EmployeeAdded(timestamp: Long, employeeId: EmployeeId, employee: Employee) extends PayrollEvent
277
+ case class EmployeeRemoved(timestamp: Long, employeeId: EmployeeId) extends PayrollEvent
278
+ case class TimeCardAdded(timestamp: Long, employeeId: EmployeeId, timeCard: TimeCard) extends PayrollEvent
279
+ case class PayrollRun(timestamp: Long, employeeId: EmployeeId, amount: Money) extends PayrollEvent
280
+
281
+ class EventStore:
282
+ private var events: List[PayrollEvent] = Nil
283
+ def append(event: PayrollEvent): Unit = events = event :: events
284
+ def getEvents: List[PayrollEvent] = events.reverse
285
+ def getEventsByEmployee(employeeId: EmployeeId): List[PayrollEvent] = ...
286
+ ```
287
+
288
+ ## 11. DSL
289
+
290
+ ```scala
291
+ object PayrollDSL:
292
+ def employee(id: EmployeeId)(name: String): EmployeeBuilder =
293
+ EmployeeBuilder(id, name)
294
+
295
+ case class EmployeeBuilder(...):
296
+ def salaried(salary: Money): EmployeeBuilder = ...
297
+ def hourly(rate: Money): EmployeeBuilder = ...
298
+ def commissioned(basePay: Money, commissionRate: Rate): EmployeeBuilder = ...
299
+ def withDirectDeposit(account: String): EmployeeBuilder = ...
300
+ def withMailPayment(address: String): EmployeeBuilder = ...
301
+ def build: Employee = ...
302
+
303
+ // 使用例
304
+ import PayrollDSL.*
305
+ val emp = employee("E001")("田中太郎")
306
+ .salaried(BigDecimal(500000))
307
+ .withDirectDeposit("1234567890")
308
+ .build
309
+ ```
310
+
311
+ ## 12. Clojure との比較
312
+
313
+ | 概念 | Clojure | Scala |
314
+ |------|---------|-------|
315
+ | ドメインモデル | マップ + Spec | case class + sealed trait |
316
+ | 多態性 | マルチメソッド | パターンマッチ / 型クラス |
317
+ | 給与計算 | `defmulti`/`defmethod` | `given`/`summon` |
318
+ | 支払い方法 | キーワード | enum |
319
+ | コンテキスト | マップ | case class |
320
+
321
+ ## 13. 関数型アプローチの利点
322
+
323
+ 1. **テスト容易性**: 純粋関数なのでテストが簡単
324
+ 2. **拡張容易性**: 新しい給与タイプは新しい型クラスインスタンスを追加するだけ
325
+ 3. **関心の分離**: 給与計算、スケジュール判定、支払い処理が分離
326
+ 4. **型安全性**: コンパイル時に多くのエラーを検出
327
+
328
+ ## まとめ
329
+
330
+ 本章では、給与計算システムを通じて以下を学びました:
331
+
332
+ 1. **ドメインモデリング**: sealed trait と case class による表現
333
+ 2. **型クラス**: 給与タイプによる多態的な計算
334
+ 3. **イミュータブル設計**: すべての操作が新しいインスタンスを返す
335
+ 4. **DSL**: 流暢なAPIによる従業員定義
336
+
337
+ ## 参考コード
338
+
339
+ 本章のコード例は以下のファイルで確認できます:
340
+
341
+ - ソースコード: `apps/scala/part6/src/main/scala/PayrollSystem.scala`
342
+ - テストコード: `apps/scala/part6/src/test/scala/PayrollSystemSpec.scala`
@@ -0,0 +1,324 @@
1
+ # 第17章: レンタルビデオシステム
2
+
3
+ ## はじめに
4
+
5
+ 本章では、Martin Fowler の「リファクタリング」で有名なレンタルビデオシステムを題材に、関数型プログラミングによる料金計算ロジックの設計を学びます。
6
+
7
+ この問題を通じて以下の概念を学びます:
8
+
9
+ - パターンマッチによる料金計算
10
+ - 明細書フォーマッターの実装
11
+ - データと処理の分離
12
+ - DSL による流暢な API
13
+
14
+ ## 1. ドメインモデル
15
+
16
+ ### 映画カテゴリ
17
+
18
+ レンタルビデオシステムでは、以下の3種類の映画カテゴリをサポートします:
19
+
20
+ - **通常(Regular)**: 2日まで2.0、以降1日ごとに1.5追加
21
+ - **新作(New Release)**: 1日ごとに3.0
22
+ - **子供向け(Children's)**: 3日まで1.5、以降1日ごとに1.5追加
23
+
24
+ ```scala
25
+ enum MovieCategory:
26
+ case Regular // 通常
27
+ case NewRelease // 新作
28
+ case Childrens // 子供向け
29
+ ```
30
+
31
+ ### 映画
32
+
33
+ ```scala
34
+ case class Movie(title: String, category: MovieCategory)
35
+
36
+ object Movie:
37
+ def regular(title: String): Movie = Movie(title, MovieCategory.Regular)
38
+ def newRelease(title: String): Movie = Movie(title, MovieCategory.NewRelease)
39
+ def childrens(title: String): Movie = Movie(title, MovieCategory.Childrens)
40
+ ```
41
+
42
+ ### レンタルと顧客
43
+
44
+ ```scala
45
+ case class Rental(movie: Movie, days: Days)
46
+
47
+ case class Customer(name: String, rentals: List[Rental] = Nil):
48
+ def addRental(rental: Rental): Customer = copy(rentals = rentals :+ rental)
49
+ ```
50
+
51
+ ## 2. 料金計算
52
+
53
+ ### 料金計算器
54
+
55
+ ```scala
56
+ trait PriceCalculator:
57
+ def calculateAmount(days: Days): Money
58
+ def calculatePoints(days: Days): Points
59
+
60
+ object RegularPricing extends PriceCalculator:
61
+ def calculateAmount(days: Days): Money =
62
+ if days > 2 then BigDecimal(2.0) + BigDecimal((days - 2) * 1.5)
63
+ else BigDecimal(2.0)
64
+ def calculatePoints(days: Days): Points = 1
65
+
66
+ object NewReleasePricing extends PriceCalculator:
67
+ def calculateAmount(days: Days): Money = BigDecimal(days * 3.0)
68
+ def calculatePoints(days: Days): Points = if days > 1 then 2 else 1
69
+
70
+ object ChildrensPricing extends PriceCalculator:
71
+ def calculateAmount(days: Days): Money =
72
+ if days > 3 then BigDecimal(1.5) + BigDecimal((days - 3) * 1.5)
73
+ else BigDecimal(1.5)
74
+ def calculatePoints(days: Days): Points = 1
75
+ ```
76
+
77
+ ### 計算例
78
+
79
+ | カテゴリ | 日数 | 料金計算 | 結果 |
80
+ |---------|------|---------|------|
81
+ | 通常 | 2日 | 2.0 | 2.0 |
82
+ | 通常 | 5日 | 2.0 + 3 * 1.5 | 6.5 |
83
+ | 新作 | 3日 | 3 * 3.0 | 9.0 |
84
+ | 子供向け | 3日 | 1.5 | 1.5 |
85
+ | 子供向け | 6日 | 1.5 + 3 * 1.5 | 6.0 |
86
+
87
+ ## 3. 明細データ
88
+
89
+ ```scala
90
+ case class RentalLine(
91
+ title: String,
92
+ days: Days,
93
+ amount: Money,
94
+ points: Points
95
+ )
96
+
97
+ case class StatementData(
98
+ customerName: String,
99
+ rentalLines: List[RentalLine],
100
+ totalAmount: Money,
101
+ totalPoints: Points
102
+ )
103
+
104
+ def generateStatementData(customer: Customer): StatementData =
105
+ val lines = customer.rentals.map { rental =>
106
+ RentalLine(
107
+ title = rental.movie.title,
108
+ days = rental.days,
109
+ amount = calculateRentalAmount(rental),
110
+ points = calculateRentalPoints(rental)
111
+ )
112
+ }
113
+ StatementData(
114
+ customerName = customer.name,
115
+ rentalLines = lines,
116
+ totalAmount = totalAmount(customer.rentals),
117
+ totalPoints = totalPoints(customer.rentals)
118
+ )
119
+ ```
120
+
121
+ ## 4. 明細書フォーマッター
122
+
123
+ ### フォーマット形式
124
+
125
+ ```scala
126
+ enum StatementFormat:
127
+ case Text
128
+ case Html
129
+ case Json
130
+ ```
131
+
132
+ ### テキスト形式
133
+
134
+ ```scala
135
+ object TextFormatter extends StatementFormatter:
136
+ def format(data: StatementData): String =
137
+ val header = s"Rental Record for ${data.customerName}\n"
138
+ val lines = data.rentalLines.map { line =>
139
+ s"\t${line.title}\t${line.amount}\n"
140
+ }.mkString
141
+ val footer = s"Amount owed is ${data.totalAmount}\n" +
142
+ s"You earned ${data.totalPoints} frequent renter points"
143
+ header + lines + footer
144
+ ```
145
+
146
+ ### HTML形式
147
+
148
+ ```scala
149
+ object HtmlFormatter extends StatementFormatter:
150
+ def format(data: StatementData): String =
151
+ val header = s"<h1>Rental Record for <em>${data.customerName}</em></h1>\n<ul>\n"
152
+ val lines = data.rentalLines.map { line =>
153
+ s" <li>${line.title} - ${line.amount}</li>\n"
154
+ }.mkString
155
+ val footer = s"</ul>\n" +
156
+ s"<p>Amount owed is <strong>${data.totalAmount}</strong></p>\n" +
157
+ s"<p>You earned <strong>${data.totalPoints}</strong> frequent renter points</p>"
158
+ header + lines + footer
159
+ ```
160
+
161
+ ### 出力例
162
+
163
+ **テキスト形式:**
164
+ ```
165
+ Rental Record for John
166
+ Inception 3.5
167
+ Frozen 3.0
168
+ New Movie 6.0
169
+ Amount owed is 12.5
170
+ You earned 4 frequent renter points
171
+ ```
172
+
173
+ **HTML形式:**
174
+ ```html
175
+ <h1>Rental Record for <em>John</em></h1>
176
+ <ul>
177
+ <li>Inception - 3.5</li>
178
+ <li>Frozen - 3.0</li>
179
+ <li>New Movie - 6.0</li>
180
+ </ul>
181
+ <p>Amount owed is <strong>12.5</strong></p>
182
+ <p>You earned <strong>4</strong> frequent renter points</p>
183
+ ```
184
+
185
+ ## 5. ポリシーベースの設計
186
+
187
+ より柔軟な設計として、料金ポリシーを関数として表現できます。
188
+
189
+ ```scala
190
+ case class PricingPolicy(
191
+ name: String,
192
+ calculateAmount: Days => Money,
193
+ calculatePoints: Days => Points
194
+ )
195
+
196
+ object PricingPolicies:
197
+ val regular: PricingPolicy = PricingPolicy(
198
+ "Regular",
199
+ days => if days > 2 then BigDecimal(2.0 + (days - 2) * 1.5) else BigDecimal(2.0),
200
+ _ => 1
201
+ )
202
+
203
+ val premium: PricingPolicy = PricingPolicy(
204
+ "Premium",
205
+ days => BigDecimal(days * 5.0),
206
+ days => days // 日数分のポイント
207
+ )
208
+ ```
209
+
210
+ ## 6. レンタルショップ
211
+
212
+ ```scala
213
+ class RentalShop:
214
+ private var movies: Map[String, Movie] = Map.empty
215
+ private var customers: Map[String, Customer] = Map.empty
216
+
217
+ def addMovie(movie: Movie): Unit = ...
218
+ def registerCustomer(name: String): Customer = ...
219
+ def rentMovie(customerName: String, movieTitle: String, days: Days): Option[Rental] = ...
220
+ def generateCustomerStatement(customerName: String, format: StatementFormat): Option[String] = ...
221
+ ```
222
+
223
+ ## 7. 割引計算
224
+
225
+ ```scala
226
+ sealed trait Discount:
227
+ def apply(amount: Money): Money
228
+
229
+ case class PercentageDiscount(percent: Double) extends Discount:
230
+ def apply(amount: Money): Money = amount * BigDecimal(1 - percent)
231
+
232
+ case class FixedDiscount(value: Money) extends Discount:
233
+ def apply(amount: Money): Money = (amount - value) max BigDecimal(0)
234
+
235
+ def applyDiscounts(amount: Money, discounts: Seq[Discount]): Money =
236
+ discounts.foldLeft(amount)((acc, d) => d.apply(acc))
237
+ ```
238
+
239
+ ## 8. 売上レポート
240
+
241
+ ```scala
242
+ case class SalesReport(
243
+ period: String,
244
+ totalRentals: Int,
245
+ totalRevenue: Money,
246
+ rentalsByCategory: Map[MovieCategory, Int],
247
+ revenueByCategory: Map[MovieCategory, Money]
248
+ )
249
+
250
+ def generateSalesReport(rentals: Seq[Rental], period: String): SalesReport =
251
+ val rentalsByCategory = rentals.groupBy(_.movie.category).view.mapValues(_.size).toMap
252
+ val revenueByCategory = rentals.groupBy(_.movie.category).view.mapValues(rs => totalAmount(rs)).toMap
253
+ SalesReport(period, rentals.size, totalAmount(rentals), rentalsByCategory, revenueByCategory)
254
+ ```
255
+
256
+ ## 9. DSL
257
+
258
+ ```scala
259
+ object RentalDSL:
260
+ def customer(name: String): CustomerBuilder = CustomerBuilder(name)
261
+
262
+ case class CustomerBuilder(name: String, rentals: List[Rental] = Nil):
263
+ def rents(movie: Movie, days: Days): CustomerBuilder =
264
+ copy(rentals = rentals :+ Rental(movie, days))
265
+ def build: Customer = Customer(name, rentals)
266
+ def statement: String = generateStatement(build)
267
+ def statementAs(format: StatementFormat): String = generateStatement(build, format)
268
+
269
+ def regular(title: String): Movie = Movie.regular(title)
270
+ def newRelease(title: String): Movie = Movie.newRelease(title)
271
+ def childrens(title: String): Movie = Movie.childrens(title)
272
+
273
+ // 使用例
274
+ import RentalDSL.*
275
+ val statement = customer("John")
276
+ .rents(regular("Inception"), 3)
277
+ .rents(newRelease("New Movie"), 2)
278
+ .statement
279
+ ```
280
+
281
+ ## 10. Clojure との比較
282
+
283
+ | 概念 | Clojure | Scala |
284
+ |------|---------|-------|
285
+ | 映画カテゴリ | キーワード (`:regular`) | enum |
286
+ | 料金計算 | マルチメソッド | パターンマッチ / object |
287
+ | 明細データ | マップ | case class |
288
+ | フォーマッター | マルチメソッド | trait + object |
289
+
290
+ ## 11. リファクタリングのポイント
291
+
292
+ ### OOP vs FP
293
+
294
+ **OOP アプローチ:**
295
+ - `Movie` クラスに `getCharge()` メソッド
296
+ - サブクラスでオーバーライド
297
+
298
+ **FP アプローチ:**
299
+ - 映画はデータのみ(case class)
300
+ - 料金計算は別の関数/object
301
+ - カテゴリに応じたディスパッチ
302
+
303
+ ### 利点
304
+
305
+ 1. **データと処理の分離**: テストが容易
306
+ 2. **拡張容易性**: 新しいカテゴリ追加が容易
307
+ 3. **オープン・クローズド原則**: 既存コード変更不要
308
+
309
+ ## まとめ
310
+
311
+ 本章では、レンタルビデオシステムを通じて以下を学びました:
312
+
313
+ 1. **パターンマッチ**: カテゴリによる料金計算のディスパッチ
314
+ 2. **データと処理の分離**: 映画データと計算ロジックの分離
315
+ 3. **フォーマッターパターン**: 複数の出力形式への対応
316
+ 4. **拡張性**: 新しいカテゴリやフォーマットの追加が容易
317
+ 5. **DSL**: 流暢な API による読みやすいコード
318
+
319
+ ## 参考コード
320
+
321
+ 本章のコード例は以下のファイルで確認できます:
322
+
323
+ - ソースコード: `apps/scala/part6/src/main/scala/VideoRentalSystem.scala`
324
+ - テストコード: `apps/scala/part6/src/test/scala/VideoRentalSystemSpec.scala`