@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,88 @@
1
+ # 第 5 章: パッケージ管理と静的解析
2
+
3
+ ## 5.1 はじめに
4
+
5
+ この章では、Elixir の依存管理とコード品質チェックを扱います。`Mix`、`Hex`、`Credo`、`mix format`、複雑度チェックを組み合わせ、TDD の継続速度と品質を両立します。
6
+
7
+ ## 5.2 Mix による依存管理
8
+
9
+ Elixir の依存関係は `mix.exs` の `deps/0` で定義します。
10
+
11
+ ```elixir
12
+ # apps/elixir/mix.exs
13
+
14
+ defp deps do
15
+ [
16
+ {:credo, "~> 1.7", only: [:dev, :test], runtime: false}
17
+ ]
18
+ end
19
+ ```
20
+
21
+ 依存追加後は `mix deps.get` で取得します。
22
+
23
+ ```bash
24
+ cd apps/elixir
25
+ mix deps.get
26
+ ```
27
+
28
+ `only: [:dev, :test]` を使うと、開発時だけ必要なツール依存を本番実行から分離できます。
29
+
30
+ ## 5.3 Hex パッケージマネージャ
31
+
32
+ `Hex` は Elixir の公式パッケージレジストリです。`mix deps.get` は `Hex` から依存を解決し、`mix.lock` にバージョンを固定します。
33
+
34
+ 日常的に使う操作は次のとおりです。
35
+
36
+ ```bash
37
+ mix deps.get # 依存取得
38
+ mix deps.update all # 依存更新
39
+ mix deps.tree # 依存ツリー確認
40
+ ```
41
+
42
+ チーム開発では `mix.lock` をコミットし、依存の再現性を確保します。
43
+
44
+ ## 5.4 Credo による静的解析
45
+
46
+ `Credo` は Elixir の静的解析ツールです。本プロジェクトでは厳格モードを使います。
47
+
48
+ ```bash
49
+ mix credo --strict
50
+ ```
51
+
52
+ `--strict` は警告を増やし、早い段階で設計上の問題や可読性低下を検出できます。`apps/elixir/Makefile` でも `lint` タスクとして定義されています。
53
+
54
+ ## 5.5 mix format と .formatter.exs
55
+
56
+ コードフォーマットは `mix format` で統一します。
57
+
58
+ ```bash
59
+ mix format
60
+ mix format --check-formatted
61
+ ```
62
+
63
+ `apps/elixir/.formatter.exs` では対象ファイルを次のように設定しています。
64
+
65
+ ```elixir
66
+ [
67
+ inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
68
+ ]
69
+ ```
70
+
71
+ CI では `--check-formatted` を使い、未整形コードの混入を防ぎます。
72
+
73
+ ## 5.6 コード複雑度チェック
74
+
75
+ 本プロジェクトでは `scripts/complexity.sh` で循環複雑度を簡易計測します。
76
+
77
+ ```bash
78
+ bash scripts/complexity.sh --threshold 10 lib
79
+ ```
80
+
81
+ - `--threshold 10`: 閾値を 10 に設定
82
+ - `lib`: チェック対象ディレクトリ
83
+
84
+ このチェックを `make complexity` や CI に組み込むことで、関数の肥大化を継続的に抑制できます。
85
+
86
+ ## 5.7 まとめ
87
+
88
+ この章では、`mix.exs` の `deps` を起点にした依存管理、`Hex` によるパッケージ解決、`Credo` と `mix format` による静的品質担保、`scripts/complexity.sh` による複雑度管理を確認しました。次章では、これらを `Makefile` と CI/CD に統合します。
@@ -0,0 +1,71 @@
1
+ # 第 6 章: タスクランナーと CI/CD
2
+
3
+ ## 6.1 はじめに
4
+
5
+ この章では、ローカル開発と CI を同じ実行基盤でそろえる方法を扱います。Nix で環境差分を吸収し、`Makefile` と GitHub Actions で品質チェックを自動化します。
6
+
7
+ ## 6.2 Nix 開発環境による環境管理
8
+
9
+ 本プロジェクトの Elixir 開発環境は Nix で提供されています。次のコマンドで同一ツールチェーンに入れます。
10
+
11
+ ```bash
12
+ nix develop .#elixir
13
+ ```
14
+
15
+ この方式により、OS 差分やローカルの手動セットアップ差分を最小化できます。CI でも同じ `nix develop .#elixir` を使うため、ローカル再現性が高くなります。
16
+
17
+ ## 6.3 Makefile でのタスク管理
18
+
19
+ `apps/elixir/Makefile` には主要タスクが定義されています。
20
+
21
+ - `make test`: `mix test`
22
+ - `make fmt`: `mix format`
23
+ - `make fmt-check`: `mix format --check-formatted`
24
+ - `make lint`: `mix credo --strict`
25
+ - `make complexity`: `bash scripts/complexity.sh --threshold 10 lib`
26
+ - `make check`: `fmt-check` + `lint` + `complexity` + `test`
27
+
28
+ 開発中は `make check` を最終ゲートにすると、レビュー前の品質をそろえやすくなります。
29
+
30
+ ## 6.4 mix の監視実行と高速テスト
31
+
32
+ Elixir ではファイル更新検知に Linux 固有の `inotify-tools` は不要です。継続実行したい場合は監視実行を利用します。
33
+
34
+ ```bash
35
+ mix test --watch
36
+ ```
37
+
38
+ また、変更影響のあるテストだけを優先して回すには `--stale` が有効です。
39
+
40
+ ```bash
41
+ mix test --stale
42
+ ```
43
+
44
+ - `--watch`: 保存ごとに再実行
45
+ - `--stale`: 変更があったモジュールに関連するテスト中心で実行
46
+
47
+ 日常開発は `mix test --stale`、節目では `mix test` や `make check` を回す運用が実践的です。
48
+
49
+ ## 6.5 GitHub Actions での Nix ベース CI/CD
50
+
51
+ Elixir 用 CI は最初から Nix ベースで構築されています。`.github/workflows/elixir-ci.yml` では次の流れを実行します。
52
+
53
+ 1. `actions/checkout@v4`
54
+ 2. `cachix/install-nix-action@v30` で Nix を導入
55
+ 3. `nix develop .#elixir --command ...` で依存取得・Format・Lint・複雑度・テストを実行
56
+
57
+ 例:
58
+
59
+ ```yaml
60
+ - name: Install Nix
61
+ uses: cachix/install-nix-action@v30
62
+
63
+ - name: Run tests
64
+ run: nix develop .#elixir --command bash -c "cd apps/elixir && mix test"
65
+ ```
66
+
67
+ 重要なのは、ローカルと CI が同じ `nix develop` を起点にしている点です。これにより「ローカルでは通るが CI で失敗する」を減らせます。
68
+
69
+ ## 6.6 まとめ
70
+
71
+ この章では、`nix develop .#elixir` による環境統一、`Makefile` によるタスク標準化、`mix test --watch` / `mix test --stale` の使い分け、GitHub Actions の Nix ベース CI を確認しました。これで TDD の反復を壊さない自動化基盤が整います。
@@ -0,0 +1,110 @@
1
+ # 第 7 章: 構造体とプロトコルによるポリモーフィズム
2
+
3
+ ## 7.1 はじめに
4
+
5
+ この章では、`defstruct` と `defprotocol` を使って、Elixir で型ごとに振る舞いを切り替える方法を学びます。FizzBuzz の値オブジェクトを導入し、`Type01`、`Type02`、`Type03` が同じインターフェース `generate/1` を実装する形でポリモーフィズムを実現します。
6
+
7
+ ## 7.2 defstruct で値オブジェクトを定義する
8
+
9
+ FizzBuzz の入力値を表す値オブジェクト `FizzBuzz.Model.Value` を定義します。`@enforce_keys` で必須フィールドを宣言すると、不完全な構造体生成を防げます。
10
+
11
+ ```elixir
12
+ defmodule FizzBuzz.Model.Value do
13
+ @enforce_keys [:number]
14
+ defstruct [:number]
15
+
16
+ @type t :: %__MODULE__{
17
+ number: pos_integer()
18
+ }
19
+ end
20
+ ```
21
+
22
+ `@enforce_keys [:number]` により、`%FizzBuzz.Model.Value{}` のような生成は実行時エラーになり、`number` の設定漏れを早期に検出できます。
23
+
24
+ ## 7.3 defprotocol で共通インターフェースを定義する
25
+
26
+ 次に、生成処理の共通契約として `Generatable` プロトコルを定義します。
27
+
28
+ ```elixir
29
+ defprotocol FizzBuzz.Generatable do
30
+ @spec generate(t()) :: String.t()
31
+ def generate(value)
32
+ end
33
+ ```
34
+
35
+ プロトコルは「どの型であっても `generate/1` を呼べる」という抽象化を提供します。実際の処理は各構造体の `defimpl` で分岐します。
36
+
37
+ ## 7.4 defimpl で Type01 / Type02 / Type03 を実装する
38
+
39
+ `Type01`、`Type02`、`Type03` は、それぞれ通常数値、3 の倍数、5 の倍数を表す構造体とします。
40
+
41
+ ```elixir
42
+ defmodule FizzBuzz.Model.Type01 do
43
+ @enforce_keys [:value]
44
+ defstruct [:value]
45
+ end
46
+
47
+ defmodule FizzBuzz.Model.Type02 do
48
+ @enforce_keys [:value]
49
+ defstruct [:value]
50
+ end
51
+
52
+ defmodule FizzBuzz.Model.Type03 do
53
+ @enforce_keys [:value]
54
+ defstruct [:value]
55
+ end
56
+
57
+ defimpl FizzBuzz.Generatable, for: FizzBuzz.Model.Type01 do
58
+ def generate(%FizzBuzz.Model.Type01{value: value}), do: Integer.to_string(value.number)
59
+ end
60
+
61
+ defimpl FizzBuzz.Generatable, for: FizzBuzz.Model.Type02 do
62
+ def generate(%FizzBuzz.Model.Type02{}), do: "Fizz"
63
+ end
64
+
65
+ defimpl FizzBuzz.Generatable, for: FizzBuzz.Model.Type03 do
66
+ def generate(%FizzBuzz.Model.Type03{}), do: "Buzz"
67
+ end
68
+ ```
69
+
70
+ この設計では、呼び出し側は具体型を意識せず、`FizzBuzz.Generatable.generate/1` だけを呼べばよくなります。
71
+
72
+ ## 7.5 ExUnit でプロトコル実装を検証する
73
+
74
+ プロトコルの振る舞いは ExUnit で確認できます。
75
+
76
+ ```elixir
77
+ defmodule FizzBuzz.GeneratableTest do
78
+ use ExUnit.Case, async: true
79
+
80
+ alias FizzBuzz.Generatable
81
+ alias FizzBuzz.Model.{Type01, Type02, Type03, Value}
82
+
83
+ test "Type01 は数値文字列を返す" do
84
+ value = %Value{number: 1}
85
+ assert Generatable.generate(%Type01{value: value}) == "1"
86
+ end
87
+
88
+ test "Type02 は Fizz を返す" do
89
+ value = %Value{number: 3}
90
+ assert Generatable.generate(%Type02{value: value}) == "Fizz"
91
+ end
92
+
93
+ test "Type03 は Buzz を返す" do
94
+ value = %Value{number: 5}
95
+ assert Generatable.generate(%Type03{value: value}) == "Buzz"
96
+ end
97
+
98
+ test "Value は number が必須" do
99
+ assert_raise ArgumentError, fn ->
100
+ struct!(Value, %{})
101
+ end
102
+ end
103
+ end
104
+ ```
105
+
106
+ `struct!/2` を使うと、`@enforce_keys` の違反をテストで明示的に確認できます。
107
+
108
+ ## 7.6 まとめ
109
+
110
+ この章では、`defstruct` と `@enforce_keys` で値オブジェクトを定義し、`defprotocol` / `defimpl` で型ごとに `generate/1` を実装しました。Elixir では継承ではなく、プロトコルでポリモーフィズムを組み立てるのが実践的です。
@@ -0,0 +1,108 @@
1
+ # 第 8 章: パターンマッチとガード節
2
+
3
+ ## 8.1 はじめに
4
+
5
+ この章では、Elixir の分岐を読みやすく保つために、関数頭部のパターンマッチ、`when` ガード節、`case` と `cond` の使い分けを整理します。あわせて、タグ付きタプル `{:ok, value}` / `{:error, reason}` による結果表現も確認します。
6
+
7
+ ## 8.2 関数頭部でのパターンマッチ
8
+
9
+ Elixir では値ごとの分岐を関数定義に直接書けます。
10
+
11
+ ```elixir
12
+ defmodule FizzBuzz.Factory do
13
+ alias FizzBuzz.Model.{Type01, Type02, Type03, Value}
14
+
15
+ def create(1), do: %Type01{value: %Value{number: 1}}
16
+ def create(2), do: %Type01{value: %Value{number: 2}}
17
+ def create(3), do: %Type02{value: %Value{number: 3}}
18
+ def create(5), do: %Type03{value: %Value{number: 5}}
19
+ def create(_), do: :unsupported
20
+ end
21
+ ```
22
+
23
+ `def create(1)`、`def create(2)`、`def create(_)` のように書くと、`if` より宣言的で見通しがよくなります。
24
+
25
+ ## 8.3 ガード節で入力条件を制約する
26
+
27
+ パターンだけで不足する条件は `when` を使います。
28
+
29
+ ```elixir
30
+ defmodule FizzBuzz.Validator do
31
+ def validate(number) when is_integer(number) and number > 0, do: {:ok, number}
32
+ def validate(number) when is_integer(number), do: {:error, :non_positive}
33
+ def validate(_), do: {:error, :not_integer}
34
+ end
35
+ ```
36
+
37
+ `when is_integer(number) and number > 0` により、正常系の条件を関数シグネチャ近くで明示できます。
38
+
39
+ ## 8.4 case 式と cond 式の使い分け
40
+
41
+ `case` は「値の形」を分岐するときに向いており、`cond` は「複数の真偽条件」を評価するときに向いています。
42
+
43
+ ```elixir
44
+ defmodule FizzBuzz.Renderer do
45
+ def from_result(result) do
46
+ case result do
47
+ {:ok, value} -> "ok: #{value}"
48
+ {:error, reason} -> "error: #{reason}"
49
+ end
50
+ end
51
+
52
+ def classify(number) do
53
+ cond do
54
+ rem(number, 15) == 0 -> :fizz_buzz
55
+ rem(number, 3) == 0 -> :fizz
56
+ rem(number, 5) == 0 -> :buzz
57
+ true -> :number
58
+ end
59
+ end
60
+ end
61
+ ```
62
+
63
+ - `case`: `{:ok, value}` のようなタグ付きデータを分解する。
64
+ - `cond`: `rem/2` の結果など条件式を上から順に判定する。
65
+
66
+ ## 8.5 ExUnit で分岐をテストする
67
+
68
+ 分岐ロジックは仕様が崩れやすいため、タグ付きタプルまで含めてテストします。
69
+
70
+ ```elixir
71
+ defmodule FizzBuzz.PatternMatchingTest do
72
+ use ExUnit.Case, async: true
73
+
74
+ alias FizzBuzz.Factory
75
+ alias FizzBuzz.Renderer
76
+ alias FizzBuzz.Validator
77
+ alias FizzBuzz.Model.Type02
78
+
79
+ test "create/1 は 3 を Type02 として生成する" do
80
+ assert %Type02{} = Factory.create(3)
81
+ end
82
+
83
+ test "validate/1 は正の整数を {:ok, value} で返す" do
84
+ assert Validator.validate(10) == {:ok, 10}
85
+ end
86
+
87
+ test "validate/1 は不正な入力を {:error, reason} で返す" do
88
+ assert Validator.validate(0) == {:error, :non_positive}
89
+ assert Validator.validate("10") == {:error, :not_integer}
90
+ end
91
+
92
+ test "from_result/1 はタグ付きタプルを文字列化する" do
93
+ assert Renderer.from_result({:ok, "Fizz"}) == "ok: Fizz"
94
+ assert Renderer.from_result({:error, :not_integer}) == "error: not_integer"
95
+ end
96
+
97
+ test "classify/1 は cond で優先順位どおりに判定する" do
98
+ assert Renderer.classify(15) == :fizz_buzz
99
+ assert Renderer.classify(6) == :fizz
100
+ assert Renderer.classify(10) == :buzz
101
+ assert Renderer.classify(7) == :number
102
+ end
103
+ end
104
+ ```
105
+
106
+ ## 8.6 まとめ
107
+
108
+ この章では、関数頭部のパターンマッチ、`when` ガード節、`case` と `cond` の使い分け、タグ付きタプルによる結果表現を確認しました。これらを組み合わせると、分岐が増えても読みやすさと安全性を維持できます。
@@ -0,0 +1,104 @@
1
+ # 第 9 章: モジュール設計とビヘイビア
2
+
3
+ ## 9.1 はじめに
4
+
5
+ この章では、モジュールの責務分割を保ちながら拡張しやすい構成を作るために、モジュールの入れ子、`@behaviour` / `@callback`、`alias` を使った設計を扱います。FizzBuzz のコマンド層を例に、共通インターフェースを実装する形へ整理します。
6
+
7
+ ## 9.2 モジュールの入れ子で責務を表現する
8
+
9
+ Elixir はファイル階層とは独立して、名前空間で責務を整理できます。たとえば `FizzBuzz.Command.ValueCommand` は「単一値を扱うコマンド」を明確に示します。
10
+
11
+ ```elixir
12
+ defmodule FizzBuzz.Command.ValueCommand do
13
+ def run(number), do: Integer.to_string(number)
14
+ end
15
+ ```
16
+
17
+ `FizzBuzz.Command` 配下に `ValueCommand` と `ListCommand` を置くと、同じ関心事のモジュール群を把握しやすくなります。
18
+
19
+ ## 9.3 @behaviour と @callback でインターフェースを定義する
20
+
21
+ まずはコマンド共通の契約を `FizzBuzz.Command` ビヘイビアとして定義します。
22
+
23
+ ```elixir
24
+ defmodule FizzBuzz.Command do
25
+ @callback run(input :: term()) :: {:ok, term()} | {:error, atom()}
26
+ end
27
+ ```
28
+
29
+ この `@callback` により、実装モジュールは `run/1` を提供する必要があります。未実装の場合、コンパイル時に警告が出るため、設計の抜け漏れを防げます。
30
+
31
+ ## 9.4 ValueCommand と ListCommand でビヘイビアを実装する
32
+
33
+ `@behaviour FizzBuzz.Command` を指定し、`run/1` を実装します。`alias` を使ってモジュール参照を簡略化します。
34
+
35
+ ```elixir
36
+ defmodule FizzBuzz.Command.ValueCommand do
37
+ @behaviour FizzBuzz.Command
38
+
39
+ alias FizzBuzz.FizzBuzzService
40
+
41
+ @impl true
42
+ def run(number) when is_integer(number) and number > 0 do
43
+ {:ok, FizzBuzzService.generate(number)}
44
+ end
45
+
46
+ @impl true
47
+ def run(_), do: {:error, :invalid_number}
48
+ end
49
+
50
+ defmodule FizzBuzz.Command.ListCommand do
51
+ @behaviour FizzBuzz.Command
52
+
53
+ alias FizzBuzz.FizzBuzzService
54
+
55
+ @impl true
56
+ def run(limit) when is_integer(limit) and limit > 0 do
57
+ values =
58
+ 1..limit
59
+ |> Enum.map(&FizzBuzzService.generate/1)
60
+
61
+ {:ok, values}
62
+ end
63
+
64
+ @impl true
65
+ def run(_), do: {:error, :invalid_limit}
66
+ end
67
+ ```
68
+
69
+ `alias FizzBuzz.FizzBuzzService` を使うことで、`FizzBuzz.FizzBuzzService.generate/1` を `FizzBuzzService.generate/1` と短く書けます。
70
+
71
+ ## 9.5 ExUnit でビヘイビア実装を検証する
72
+
73
+ 各コマンドが同じ契約で動くことを ExUnit で確認します。
74
+
75
+ ```elixir
76
+ defmodule FizzBuzz.CommandTest do
77
+ use ExUnit.Case, async: true
78
+
79
+ alias FizzBuzz.Command.{ListCommand, ValueCommand}
80
+
81
+ test "ValueCommand は単一値を処理する" do
82
+ assert ValueCommand.run(3) == {:ok, "Fizz"}
83
+ end
84
+
85
+ test "ValueCommand は不正値でエラーを返す" do
86
+ assert ValueCommand.run(0) == {:error, :invalid_number}
87
+ assert ValueCommand.run("3") == {:error, :invalid_number}
88
+ end
89
+
90
+ test "ListCommand は 1..limit の結果一覧を返す" do
91
+ assert ListCommand.run(5) == {:ok, ["1", "2", "Fizz", "4", "Buzz"]}
92
+ end
93
+
94
+ test "ListCommand は不正値でエラーを返す" do
95
+ assert ListCommand.run(-1) == {:error, :invalid_limit}
96
+ end
97
+ end
98
+ ```
99
+
100
+ `ValueCommand` と `ListCommand` は入出力対象が異なっても、同じ `run/1` 契約を守るため、呼び出し側の扱いを統一できます。
101
+
102
+ ## 9.6 まとめ
103
+
104
+ この章では、`FizzBuzz.Command.ValueCommand` のようなモジュール入れ子で責務を整理し、`@behaviour` / `@callback` で契約を固定し、`alias` で記述を簡潔にする方法を確認しました。ビヘイビア中心の設計により、機能追加時も既存コードへの影響を局所化できます。
@@ -0,0 +1,178 @@
1
+ # 第 10 章: 高階関数とパイプライン演算子
2
+
3
+ ## 10.1 はじめに
4
+
5
+ この章では、Elixir の高階関数を使って、データ変換を宣言的に記述する方法を学びます。`Enum.map`、`Enum.filter`、`Enum.reduce`、無名関数、`|>` パイプライン演算子を組み合わせ、FizzBuzz の実装を拡張します。
6
+
7
+ ## 10.2 高階関数の基本: Enum.map / Enum.filter / Enum.reduce
8
+
9
+ 高階関数は、関数を引数として受け取る関数です。Elixir では `Enum` モジュールが代表例です。
10
+
11
+ ```elixir
12
+ defmodule FizzBuzz.Functional do
13
+ def generate(number) when rem(number, 15) == 0, do: "FizzBuzz"
14
+ def generate(number) when rem(number, 3) == 0, do: "Fizz"
15
+ def generate(number) when rem(number, 5) == 0, do: "Buzz"
16
+ def generate(number), do: Integer.to_string(number)
17
+
18
+ def generate_list(limit) do
19
+ 1..limit
20
+ |> Enum.map(&generate/1)
21
+ end
22
+
23
+ def count_fizzbuzz(limit) do
24
+ 1..limit
25
+ |> Enum.map(&generate/1)
26
+ |> Enum.filter(&(&1 in ["Fizz", "Buzz", "FizzBuzz"]))
27
+ |> Enum.count()
28
+ end
29
+
30
+ def summary(limit) do
31
+ 1..limit
32
+ |> Enum.map(&generate/1)
33
+ |> Enum.reduce(%{fizz: 0, buzz: 0, fizzbuzz: 0, number: 0}, fn value, acc ->
34
+ case value do
35
+ "Fizz" -> %{acc | fizz: acc.fizz + 1}
36
+ "Buzz" -> %{acc | buzz: acc.buzz + 1}
37
+ "FizzBuzz" -> %{acc | fizzbuzz: acc.fizzbuzz + 1}
38
+ _ -> %{acc | number: acc.number + 1}
39
+ end
40
+ end)
41
+ end
42
+ end
43
+ ```
44
+
45
+ ## 10.3 無名関数: fn と & キャプチャ演算子
46
+
47
+ Elixir には 2 つの無名関数の書き方があります。
48
+
49
+ ```elixir
50
+ defmodule FizzBuzz.Anonymous do
51
+ def multiply_all(numbers, factor) do
52
+ Enum.map(numbers, fn n -> n * factor end)
53
+ end
54
+
55
+ def square_all(numbers) do
56
+ Enum.map(numbers, &(&1 * &1))
57
+ end
58
+
59
+ def stringify(numbers) do
60
+ Enum.map(numbers, &Integer.to_string/1)
61
+ end
62
+ end
63
+ ```
64
+
65
+ - `fn n -> ... end` は複雑なロジックに向いています。
66
+ - `&(&1 * &1)` のようなキャプチャ演算子は短く書けます。
67
+
68
+ ## 10.4 パイプライン演算子 |> で関数チェーンを書く
69
+
70
+ `|>` は左側の値を右側関数の第 1 引数に渡します。処理の流れを上から下に読めるため、可読性が上がります。
71
+
72
+ ```elixir
73
+ defmodule FizzBuzz.Pipeline do
74
+ alias FizzBuzz.Functional
75
+
76
+ def report(limit) do
77
+ 1..limit
78
+ |> Enum.map(&Functional.generate/1)
79
+ |> Enum.filter(&(&1 != "FizzBuzz"))
80
+ |> Enum.join(",")
81
+ end
82
+ end
83
+ ```
84
+
85
+ ## 10.5 generate_with/2 でカスタムルール関数を受け取る
86
+
87
+ 高階関数を使うと、ルールを外部から注入できます。`generate_with/2` は「数値」と「ルール関数」を受け取ります。
88
+
89
+ ```elixir
90
+ defmodule FizzBuzz.CustomRule do
91
+ def generate_with(number, rule_fn) when is_function(rule_fn, 1) do
92
+ case rule_fn.(number) do
93
+ nil -> Integer.to_string(number)
94
+ value -> value
95
+ end
96
+ end
97
+
98
+ def generate_with(number, rule_fns) when is_list(rule_fns) do
99
+ result =
100
+ Enum.reduce_while(rule_fns, nil, fn rule_fn, _acc ->
101
+ case rule_fn.(number) do
102
+ nil -> {:cont, nil}
103
+ value -> {:halt, value}
104
+ end
105
+ end)
106
+
107
+ result || Integer.to_string(number)
108
+ end
109
+ end
110
+ ```
111
+
112
+ ## 10.6 transform/2 と filter/2 で汎用化する
113
+
114
+ FizzBuzz 専用処理を汎用関数に切り出すと、再利用しやすくなります。
115
+
116
+ ```elixir
117
+ defmodule FizzBuzz.Collection do
118
+ def transform(values, mapper) when is_function(mapper, 1) do
119
+ Enum.map(values, mapper)
120
+ end
121
+
122
+ def filter(values, predicate) when is_function(predicate, 1) do
123
+ Enum.filter(values, predicate)
124
+ end
125
+ end
126
+ ```
127
+
128
+ ## 10.7 ExUnit で高階関数を検証する
129
+
130
+ ```elixir
131
+ defmodule FizzBuzz.HigherOrderFunctionsTest do
132
+ use ExUnit.Case, async: true
133
+
134
+ alias FizzBuzz.{Collection, CustomRule, Functional}
135
+
136
+ test "Enum.map で FizzBuzz の一覧を生成できる" do
137
+ assert Functional.generate_list(5) == ["1", "2", "Fizz", "4", "Buzz"]
138
+ end
139
+
140
+ test "Enum.filter と Enum.count で Fizz/Buzz 系だけ数えられる" do
141
+ assert Functional.count_fizzbuzz(15) == 7
142
+ end
143
+
144
+ test "Enum.reduce で種別ごとの集計ができる" do
145
+ assert Functional.summary(15) == %{fizz: 4, buzz: 2, fizzbuzz: 1, number: 8}
146
+ end
147
+
148
+ test "generate_with/2 は単一ルール関数を受け取れる" do
149
+ even_rule = fn n -> if rem(n, 2) == 0, do: "Even", else: nil end
150
+
151
+ assert CustomRule.generate_with(4, even_rule) == "Even"
152
+ assert CustomRule.generate_with(3, even_rule) == "3"
153
+ end
154
+
155
+ test "generate_with/2 はルール関数リストを順に適用する" do
156
+ rules = [
157
+ fn n -> if rem(n, 7) == 0, do: "Pop", else: nil end,
158
+ fn n -> if rem(n, 3) == 0, do: "Fizz", else: nil end
159
+ ]
160
+
161
+ assert CustomRule.generate_with(14, rules) == "Pop"
162
+ assert CustomRule.generate_with(9, rules) == "Fizz"
163
+ assert CustomRule.generate_with(2, rules) == "2"
164
+ end
165
+
166
+ test "transform/2 と filter/2 を組み合わせて再利用できる" do
167
+ values = 1..6 |> Enum.to_list()
168
+
169
+ assert values
170
+ |> Collection.transform(&(&1 * 10))
171
+ |> Collection.filter(&(&1 > 30)) == [40, 50, 60]
172
+ end
173
+ end
174
+ ```
175
+
176
+ ## 10.8 まとめ
177
+
178
+ この章では、高階関数、無名関数、`|>` パイプライン演算子を使って処理を小さな関数へ分解し、合成する方法を確認しました。`generate_with/2`、`transform/2`、`filter/2` のように関数を受け取る設計により、仕様変更に強い実装を作れます。