@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,687 @@
1
+ # 第6章: テスト駆動開発と関数型プログラミング
2
+
3
+ ## はじめに
4
+
5
+ テスト駆動開発(TDD)は、テストを先に書いてから実装を行う開発手法です。関数型プログラミングと TDD は相性が良く、純粋関数はテストが容易で、不変データ構造は予測可能な動作を保証します。
6
+
7
+ 本章では、Red-Green-Refactor サイクルを関数型スタイルで実践する方法を学びます。
8
+
9
+ ## 1. TDD の基本サイクル
10
+
11
+ ### Red-Green-Refactor
12
+
13
+ ```
14
+ ┌─────────────────────────────────────────────────┐
15
+ │ │
16
+ │ ┌───────┐ ┌───────┐ ┌───────────┐ │
17
+ │ │ Red │ ──► │ Green │ ──► │ Refactor │ │
18
+ │ └───────┘ └───────┘ └───────────┘ │
19
+ │ ▲ │ │
20
+ │ └──────────────────────────────┘ │
21
+ │ │
22
+ └─────────────────────────────────────────────────┘
23
+ ```
24
+
25
+ 1. **Red(赤)**: 失敗するテストを書く
26
+ 2. **Green(緑)**: テストを通す最小限のコードを書く
27
+ 3. **Refactor(リファクタリング)**: コードを改善する(テストは通ったまま)
28
+
29
+ ## 2. FizzBuzz - TDD の典型例
30
+
31
+ ### Step 1: Red(最初のテスト)
32
+
33
+ ```fsharp
34
+ [<Fact>]
35
+ let ``fizzbuzz 1は"1"を返す`` () =
36
+ Assert.Equal("1", fizzbuzz 1)
37
+ ```
38
+
39
+ ### Step 2: Green(最小限の実装)
40
+
41
+ ```fsharp
42
+ let fizzbuzz n = "1"
43
+ ```
44
+
45
+ ### Step 3: 次のテストを追加して段階的に実装を発展
46
+
47
+ ```fsharp
48
+ // テストを追加
49
+ [<Fact>]
50
+ let ``fizzbuzz 2は"2"を返す`` () =
51
+ Assert.Equal("2", fizzbuzz 2)
52
+
53
+ [<Fact>]
54
+ let ``fizzbuzz 3は"Fizz"を返す`` () =
55
+ Assert.Equal("Fizz", fizzbuzz 3)
56
+
57
+ [<Fact>]
58
+ let ``fizzbuzz 5は"Buzz"を返す`` () =
59
+ Assert.Equal("Buzz", fizzbuzz 5)
60
+
61
+ [<Fact>]
62
+ let ``fizzbuzz 15は"FizzBuzz"を返す`` () =
63
+ Assert.Equal("FizzBuzz", fizzbuzz 15)
64
+ ```
65
+
66
+ ### 最終実装(小さなヘルパー関数に分割)
67
+
68
+ ```fsharp
69
+ /// 3で割り切れるかどうか
70
+ let isFizz n = n % 3 = 0
71
+
72
+ /// 5で割り切れるかどうか
73
+ let isBuzz n = n % 5 = 0
74
+
75
+ /// 15で割り切れるかどうか(FizzBuzz)
76
+ let isFizzBuzz n = isFizz n && isBuzz n
77
+
78
+ /// FizzBuzz変換
79
+ let fizzbuzz n =
80
+ if isFizzBuzz n then "FizzBuzz"
81
+ elif isFizz n then "Fizz"
82
+ elif isBuzz n then "Buzz"
83
+ else string n
84
+
85
+ /// 1からnまでのFizzBuzz列を生成
86
+ let fizzbuzzSequence n =
87
+ [ 1 .. n ] |> List.map fizzbuzz
88
+ ```
89
+
90
+ ### プロパティベーステストと組み合わせ
91
+
92
+ ```fsharp
93
+ [<Property>]
94
+ let ``3の倍数は常にFizzを含む`` (n: FsCheck.PositiveInt) =
95
+ let num = n.Get * 3
96
+ let result = fizzbuzz num
97
+ result.Contains("Fizz")
98
+
99
+ [<Property>]
100
+ let ``5の倍数は常にBuzzを含む`` (n: FsCheck.PositiveInt) =
101
+ let num = n.Get * 5
102
+ let result = fizzbuzz num
103
+ result.Contains("Buzz")
104
+ ```
105
+
106
+ ## 3. ローマ数字変換
107
+
108
+ ### テストから始める
109
+
110
+ ```fsharp
111
+ [<Fact>]
112
+ let ``toRoman 1はIを返す`` () =
113
+ Assert.Equal("I", toRoman 1)
114
+
115
+ [<Fact>]
116
+ let ``toRoman 4はIVを返す`` () =
117
+ Assert.Equal("IV", toRoman 4)
118
+
119
+ [<Fact>]
120
+ let ``toRoman 1994はMCMXCIVを返す`` () =
121
+ Assert.Equal("MCMXCIV", toRoman 1994)
122
+
123
+ [<Fact>]
124
+ let ``toRomanとfromRomanは逆関数`` () =
125
+ for n in 1..100 do
126
+ Assert.Equal(n, fromRoman (toRoman n))
127
+ ```
128
+
129
+ ### データ駆動の実装
130
+
131
+ ```fsharp
132
+ /// ローマ数字の対応表(大きい順)
133
+ let private romanNumerals =
134
+ [ (1000, "M"); (900, "CM"); (500, "D"); (400, "CD")
135
+ (100, "C"); (90, "XC"); (50, "L"); (40, "XL")
136
+ (10, "X"); (9, "IX"); (5, "V"); (4, "IV")
137
+ (1, "I") ]
138
+
139
+ /// 整数をローマ数字に変換
140
+ let toRoman n =
141
+ if n <= 0 || n > 3999 then
142
+ invalidArg "n" "n must be between 1 and 3999"
143
+
144
+ let rec loop remaining result =
145
+ if remaining = 0 then
146
+ result
147
+ else
148
+ let (value, numeral) = romanNumerals |> List.find (fun (v, _) -> v <= remaining)
149
+ loop (remaining - value) (result + numeral)
150
+
151
+ loop n ""
152
+
153
+ /// ローマ数字から整数へ変換(逆変換)
154
+ let private romanValues =
155
+ Map.ofList [ ('I', 1); ('V', 5); ('X', 10); ('L', 50)
156
+ ('C', 100); ('D', 500); ('M', 1000) ]
157
+
158
+ let fromRoman (roman: string) =
159
+ let values = roman |> Seq.map (fun c -> Map.find c romanValues) |> Seq.toList
160
+
161
+ let rec loop vals acc =
162
+ match vals with
163
+ | [] -> acc
164
+ | [ x ] -> acc + x
165
+ | x :: y :: rest when x < y -> loop (y :: rest) (acc - x)
166
+ | x :: rest -> loop rest (acc + x)
167
+
168
+ loop values 0
169
+ ```
170
+
171
+ ## 4. ボウリングスコア計算
172
+
173
+ ### 複雑なビジネスロジックの TDD
174
+
175
+ ```fsharp
176
+ [<Fact>]
177
+ let ``ガタースコアは0`` () =
178
+ Assert.Equal(0, bowlingScore (List.replicate 20 0))
179
+
180
+ [<Fact>]
181
+ let ``すべて1ピンは20点`` () =
182
+ Assert.Equal(20, bowlingScore (List.replicate 20 1))
183
+
184
+ [<Fact>]
185
+ let ``スペアの後の投球はボーナス`` () =
186
+ let rolls = [ 5; 5; 3; 0 ] @ List.replicate 16 0
187
+ Assert.Equal(16, bowlingScore rolls)
188
+
189
+ [<Fact>]
190
+ let ``ストライクの後の2投はボーナス`` () =
191
+ let rolls = [ 10; 3; 4 ] @ List.replicate 16 0
192
+ Assert.Equal(24, bowlingScore rolls)
193
+
194
+ [<Fact>]
195
+ let ``パーフェクトゲームは300点`` () =
196
+ Assert.Equal(300, bowlingScore (List.replicate 12 10))
197
+ ```
198
+
199
+ ### 小さな関数に分割
200
+
201
+ ```fsharp
202
+ /// ストライクかどうか
203
+ let isStrike rolls =
204
+ match rolls with
205
+ | x :: _ -> x = 10
206
+ | [] -> false
207
+
208
+ /// スペアかどうか
209
+ let isSpare rolls =
210
+ match rolls with
211
+ | x :: y :: _ -> x + y = 10 && x <> 10
212
+ | _ -> false
213
+
214
+ /// ストライクボーナス
215
+ let strikeBonus remaining =
216
+ remaining |> List.truncate 2 |> List.sum
217
+
218
+ /// スペアボーナス
219
+ let spareBonus remaining =
220
+ remaining |> List.tryHead |> Option.defaultValue 0
221
+
222
+ /// ボウリングスコアを計算
223
+ let bowlingScore rolls =
224
+ let rec loop remainingRolls frame total =
225
+ if frame > 10 || List.isEmpty remainingRolls then
226
+ total
227
+ elif isStrike remainingRolls then
228
+ loop (List.tail remainingRolls) (frame + 1) (total + 10 + strikeBonus (List.tail remainingRolls))
229
+ elif isSpare remainingRolls then
230
+ loop (remainingRolls |> List.skip 2) (frame + 1) (total + 10 + spareBonus (remainingRolls |> List.skip 2))
231
+ else
232
+ let frameScore = remainingRolls |> List.truncate 2 |> List.sum
233
+ loop (remainingRolls |> List.skip 2) (frame + 1) (total + frameScore)
234
+
235
+ loop rolls 1 0
236
+ ```
237
+
238
+ ## 5. 素数 - シンプルな関数の TDD
239
+
240
+ ### テストから設計を導く
241
+
242
+ ```fsharp
243
+ [<Fact>]
244
+ let ``0は素数ではない`` () =
245
+ Assert.False(isPrime 0)
246
+
247
+ [<Fact>]
248
+ let ``2は素数`` () =
249
+ Assert.True(isPrime 2)
250
+
251
+ [<Fact>]
252
+ let ``primesUpTo 20は正しい素数リストを返す`` () =
253
+ let expected = [ 2; 3; 5; 7; 11; 13; 17; 19 ]
254
+ Assert.Equal<int list>(expected, primesUpTo 20)
255
+
256
+ [<Fact>]
257
+ let ``primeFactors 24は2,2,2,3を返す`` () =
258
+ let expected = [ 2; 2; 2; 3 ]
259
+ Assert.Equal<int list>(expected, primeFactors 24)
260
+
261
+ [<Fact>]
262
+ let ``primeFactorsの積は元の数に等しい`` () =
263
+ for n in 2..100 do
264
+ let factors = primeFactors n
265
+ let product = factors |> List.fold (*) 1
266
+ Assert.Equal(n, product)
267
+ ```
268
+
269
+ ### 実装
270
+
271
+ ```fsharp
272
+ /// 素数判定
273
+ let isPrime n =
274
+ if n < 2 then false
275
+ elif n = 2 then true
276
+ elif n % 2 = 0 then false
277
+ else
278
+ let sqrtN = int (sqrt (float n))
279
+ seq { 3 .. 2 .. sqrtN }
280
+ |> Seq.exists (fun i -> n % i = 0)
281
+ |> not
282
+
283
+ /// n以下の素数をすべて返す
284
+ let primesUpTo n =
285
+ [ 2 .. n ] |> List.filter isPrime
286
+
287
+ /// 素因数分解
288
+ let primeFactors n =
289
+ let rec loop remaining factor factors =
290
+ if remaining = 1 then
291
+ List.rev factors
292
+ elif remaining % factor = 0 then
293
+ loop (remaining / factor) factor (factor :: factors)
294
+ else
295
+ loop remaining (factor + 1) factors
296
+
297
+ loop n 2 []
298
+ ```
299
+
300
+ ## 6. 不変データ構造 - スタックとキュー
301
+
302
+ ### 不変スタック
303
+
304
+ ```fsharp
305
+ type Stack<'T> =
306
+ private { Items: 'T list }
307
+
308
+ member this.IsEmpty = List.isEmpty this.Items
309
+ member this.Size = List.length this.Items
310
+
311
+ member this.Push(item: 'T) = { Items = item :: this.Items }
312
+
313
+ member this.Pop() =
314
+ match this.Items with
315
+ | head :: tail -> Some(head, { Items = tail })
316
+ | [] -> None
317
+
318
+ member this.Peek() = List.tryHead this.Items
319
+
320
+ module Stack =
321
+ let empty<'T> : Stack<'T> = { Items = [] }
322
+ let push item (stack: Stack<'T>) = stack.Push(item)
323
+ let pop (stack: Stack<'T>) = stack.Pop()
324
+ let peek (stack: Stack<'T>) = stack.Peek()
325
+ let isEmpty (stack: Stack<'T>) = stack.IsEmpty
326
+ let size (stack: Stack<'T>) = stack.Size
327
+ ```
328
+
329
+ ### テスト
330
+
331
+ ```fsharp
332
+ [<Fact>]
333
+ let ``LIFO順序で動作する`` () =
334
+ let stack =
335
+ Stack.empty
336
+ |> Stack.push "a"
337
+ |> Stack.push "b"
338
+ |> Stack.push "c"
339
+
340
+ match Stack.pop stack with
341
+ | Some (v1, s1) ->
342
+ Assert.Equal("c", v1)
343
+ match Stack.pop s1 with
344
+ | Some (v2, s2) ->
345
+ Assert.Equal("b", v2)
346
+ match Stack.pop s2 with
347
+ | Some (v3, s3) ->
348
+ Assert.Equal("a", v3)
349
+ Assert.True(Stack.isEmpty s3)
350
+ | None -> Assert.Fail("Expected value")
351
+ | None -> Assert.Fail("Expected value")
352
+ | None -> Assert.Fail("Expected value")
353
+ ```
354
+
355
+ ### 不変キュー(2つのリストで実装)
356
+
357
+ ```fsharp
358
+ type Queue<'T> =
359
+ private { Front: 'T list; Back: 'T list }
360
+
361
+ member this.IsEmpty = List.isEmpty this.Front && List.isEmpty this.Back
362
+
363
+ member this.Enqueue(item: 'T) = { Front = this.Front; Back = item :: this.Back }
364
+
365
+ member this.Dequeue() =
366
+ match this.Front with
367
+ | head :: tail -> Some(head, { Front = tail; Back = this.Back })
368
+ | [] ->
369
+ match List.rev this.Back with
370
+ | head :: tail -> Some(head, { Front = tail; Back = [] })
371
+ | [] -> None
372
+
373
+ module Queue =
374
+ let empty<'T> : Queue<'T> = { Front = []; Back = [] }
375
+ let enqueue item (queue: Queue<'T>) = queue.Enqueue(item)
376
+ let dequeue (queue: Queue<'T>) = queue.Dequeue()
377
+ let isEmpty (queue: Queue<'T>) = queue.IsEmpty
378
+ ```
379
+
380
+ ## 7. 文字列電卓 - 段階的な要件追加
381
+
382
+ ### テスト
383
+
384
+ ```fsharp
385
+ [<Fact>]
386
+ let ``空文字列は0を返す`` () =
387
+ Assert.Equal(0, StringCalculator.add "")
388
+
389
+ [<Fact>]
390
+ let ``単一の数値はその値を返す`` () =
391
+ Assert.Equal(5, StringCalculator.add "5")
392
+
393
+ [<Fact>]
394
+ let ``カンマ区切りの数値を合計する`` () =
395
+ Assert.Equal(6, StringCalculator.add "1,2,3")
396
+
397
+ [<Fact>]
398
+ let ``改行区切りも処理する`` () =
399
+ Assert.Equal(6, StringCalculator.add "1\n2,3")
400
+
401
+ [<Fact>]
402
+ let ``カスタム区切り文字を使用できる`` () =
403
+ Assert.Equal(3, StringCalculator.add "//;\n1;2")
404
+
405
+ [<Fact>]
406
+ let ``負の数は例外をスローする`` () =
407
+ let ex = Assert.Throws<System.ArgumentException>(fun () ->
408
+ StringCalculator.add "1,-2,3" |> ignore)
409
+ Assert.Contains("-2", ex.Message)
410
+
411
+ [<Fact>]
412
+ let ``1000より大きい数は無視する`` () =
413
+ Assert.Equal(2, StringCalculator.add "2,1001")
414
+ ```
415
+
416
+ ### 実装
417
+
418
+ ```fsharp
419
+ module StringCalculator =
420
+ /// 区切り文字と数値文字列をパース
421
+ let private parseInput (input: string) =
422
+ if input.StartsWith("//") then
423
+ let delimiterEnd = input.IndexOf('\n')
424
+ let delimiter = input.Substring(2, delimiterEnd - 2)
425
+ let numbers = input.Substring(delimiterEnd + 1)
426
+ (delimiter, numbers)
427
+ else
428
+ (",|\n", input)
429
+
430
+ /// 数値をパース
431
+ let private parseNumbers (numbers: string) (delimiter: string) =
432
+ let regex = System.Text.RegularExpressions.Regex(delimiter)
433
+ regex.Split(numbers)
434
+ |> Array.filter (fun s -> not (System.String.IsNullOrEmpty(s)))
435
+ |> Array.map int
436
+ |> Array.toList
437
+
438
+ /// 負の数をバリデーション
439
+ let private validateNumbers (nums: int list) =
440
+ let negatives = nums |> List.filter (fun n -> n < 0)
441
+ if not (List.isEmpty negatives) then
442
+ let negStr = negatives |> List.map string |> String.concat ", "
443
+ invalidArg "input" (sprintf "negatives not allowed: %s" negStr)
444
+
445
+ /// 文字列電卓
446
+ let add (input: string) =
447
+ if System.String.IsNullOrEmpty(input) then
448
+ 0
449
+ else
450
+ let (delimiter, numbers) = parseInput input
451
+ let nums = parseNumbers numbers delimiter
452
+ validateNumbers nums
453
+ nums |> List.filter (fun n -> n <= 1000) |> List.sum
454
+ ```
455
+
456
+ ## 8. 純粋関数とテスト容易性
457
+
458
+ ### 純粋関数の利点
459
+
460
+ ```fsharp
461
+ type Item = { Name: string; Price: decimal }
462
+
463
+ type TaxCalculation =
464
+ { Subtotal: decimal
465
+ Tax: decimal
466
+ Total: decimal }
467
+
468
+ module TaxCalculator =
469
+ /// 税額を計算
470
+ let calculateTax (amount: decimal) (rate: decimal) = amount * rate
471
+
472
+ /// 税込み総額を計算
473
+ let calculateTotalWithTax (items: Item list) (taxRate: decimal) =
474
+ let subtotal = items |> List.sumBy (fun i -> i.Price)
475
+ let tax = calculateTax subtotal taxRate
476
+ { Subtotal = subtotal
477
+ Tax = tax
478
+ Total = subtotal + tax }
479
+ ```
480
+
481
+ ### テスト
482
+
483
+ ```fsharp
484
+ [<Fact>]
485
+ let ``calculateTotalWithTaxは税込み総額を計算する`` () =
486
+ let items =
487
+ [ { Name = "商品A"; Price = 1000m }
488
+ { Name = "商品B"; Price = 2000m } ]
489
+ let result = TaxCalculator.calculateTotalWithTax items 0.1m
490
+
491
+ Assert.Equal(3000m, result.Subtotal)
492
+ Assert.Equal(300m, result.Tax)
493
+ Assert.Equal(3300m, result.Total)
494
+ ```
495
+
496
+ ## 9. リファクタリングパターン - データ駆動の実装
497
+
498
+ ### Before: 複雑な条件分岐
499
+
500
+ ```fsharp
501
+ let calculateShippingBefore total weight region =
502
+ if total >= 10000m then 0
503
+ else
504
+ match region with
505
+ | Local when weight < 5.0 -> 300
506
+ | Local -> 500
507
+ | Domestic when weight < 5.0 -> 500
508
+ | Domestic -> 800
509
+ | International when weight < 5.0 -> 2000
510
+ | International -> 3000
511
+ ```
512
+
513
+ ### After: データ駆動の実装
514
+
515
+ ```fsharp
516
+ type Region =
517
+ | Local
518
+ | Domestic
519
+ | International
520
+
521
+ type ShippingOrder =
522
+ { Total: decimal
523
+ Weight: float
524
+ Region: Region }
525
+
526
+ module ShippingCalculator =
527
+ let isFreeShipping (total: decimal) = total >= 10000m
528
+
529
+ let private shippingRates =
530
+ Map.ofList
531
+ [ (Local, Map.ofList [ (true, 300); (false, 500) ])
532
+ (Domestic, Map.ofList [ (true, 500); (false, 800) ])
533
+ (International, Map.ofList [ (true, 2000); (false, 3000) ]) ]
534
+
535
+ let calculateShipping (order: ShippingOrder) =
536
+ if isFreeShipping order.Total then
537
+ 0
538
+ else
539
+ let isLight = order.Weight < 5.0
540
+ shippingRates
541
+ |> Map.tryFind order.Region
542
+ |> Option.bind (Map.tryFind isLight)
543
+ |> Option.defaultValue 500
544
+ ```
545
+
546
+ ## 10. パスワードバリデーター - ルールの合成
547
+
548
+ ```fsharp
549
+ module PasswordValidator =
550
+ type Rule = string -> string option
551
+
552
+ let minLength (min: int) : Rule =
553
+ fun password ->
554
+ if password.Length >= min then None
555
+ else Some (sprintf "Password must be at least %d characters" min)
556
+
557
+ let hasUppercase: Rule =
558
+ fun password ->
559
+ if password |> Seq.exists System.Char.IsUpper then None
560
+ else Some "Password must contain at least one uppercase letter"
561
+
562
+ let hasLowercase: Rule =
563
+ fun password ->
564
+ if password |> Seq.exists System.Char.IsLower then None
565
+ else Some "Password must contain at least one lowercase letter"
566
+
567
+ let hasDigit: Rule =
568
+ fun password ->
569
+ if password |> Seq.exists System.Char.IsDigit then None
570
+ else Some "Password must contain at least one digit"
571
+
572
+ let defaultRules: Rule list =
573
+ [ minLength 8; hasUppercase; hasLowercase; hasDigit ]
574
+
575
+ let validate (password: string) (rules: Rule list) : Result<string, string list> =
576
+ let errors = rules |> List.choose (fun rule -> rule password)
577
+ if List.isEmpty errors then Ok password
578
+ else Error errors
579
+
580
+ let validateWithDefaults (password: string) : Result<string, string list> =
581
+ validate password defaultRules
582
+ ```
583
+
584
+ ## TDD のベストプラクティス
585
+
586
+ ### 1. 小さなステップで進む
587
+
588
+ - 一度に1つのテストだけを追加
589
+ - テストが通ったら次のテストへ
590
+
591
+ ### 2. テスト名は仕様として読める
592
+
593
+ ```fsharp
594
+ [<Fact>]
595
+ let ``10000円以上は送料無料`` () = ...
596
+
597
+ [<Fact>]
598
+ let ``負の数は例外をスローする`` () = ...
599
+
600
+ [<Fact>]
601
+ let ``パーフェクトゲームは300点`` () = ...
602
+ ```
603
+
604
+ ### 3. 純粋関数を優先
605
+
606
+ - 副作用を持つ関数は最小限に
607
+ - 副作用は境界に追い出す
608
+
609
+ ### 4. エッジケースをテスト
610
+
611
+ ```fsharp
612
+ [<Fact>]
613
+ let ``空文字列は0を返す`` () = ...
614
+
615
+ [<Fact>]
616
+ let ``空のリストは空のリストを返す`` () = ...
617
+
618
+ [<Fact>]
619
+ let ``境界値で正しく動作する`` () = ...
620
+ ```
621
+
622
+ ## Clojure/Scala との比較
623
+
624
+ | 概念 | Clojure | Scala | F# |
625
+ |------|---------|-------|-----|
626
+ | テストフレームワーク | speclj, clojure.test | ScalaTest | xUnit, FsCheck |
627
+ | テスト構文 | `(it "..." (should= ...))` | `test("...") { ... shouldBe ... }` | `[<Fact>] let ``...`` () = Assert.Equal(...)` |
628
+ | 例外テスト | `(should-throw ...)` | `intercept[...] { ... }` | `Assert.Throws<...>(...)` |
629
+ | データ構造 | 永続化データ構造(デフォルト) | `case class` + `copy` | レコード型 + `with` |
630
+ | ループ | `loop/recur` | `@annotation.tailrec` | `let rec` |
631
+ | パターンマッチ | `cond`, `case` | `match` | `match` |
632
+ | 型システム | 動的型付け | 静的型付け | 静的型付け + 型推論 |
633
+
634
+ ## F# 特有のパターン
635
+
636
+ ### バッククォートテスト名
637
+
638
+ F# では日本語やスペースを含むテスト名が書ける:
639
+
640
+ ```fsharp
641
+ [<Fact>]
642
+ let ``fizzbuzz 15は"FizzBuzz"を返す`` () = ...
643
+ ```
644
+
645
+ ### Option 型による安全なアクセス
646
+
647
+ ```fsharp
648
+ member this.Pop() =
649
+ match this.Items with
650
+ | head :: tail -> Some(head, { Items = tail })
651
+ | [] -> None
652
+ ```
653
+
654
+ ### パイプライン演算子との親和性
655
+
656
+ ```fsharp
657
+ let fizzbuzzSequence n =
658
+ [ 1 .. n ] |> List.map fizzbuzz
659
+ ```
660
+
661
+ ## まとめ
662
+
663
+ 本章では、TDD と関数型プログラミングについて学びました:
664
+
665
+ 1. **Red-Green-Refactor**: 基本サイクル
666
+ 2. **FizzBuzz**: 典型的な TDD 例
667
+ 3. **ローマ数字**: データ駆動の実装
668
+ 4. **ボウリング**: 複雑なビジネスロジック
669
+ 5. **素数**: シンプルな関数設計
670
+ 6. **スタック/キュー**: 不変データ構造
671
+ 7. **文字列電卓**: 段階的な要件追加
672
+ 8. **純粋関数**: テスト容易性
673
+ 9. **リファクタリング**: 条件分岐の整理
674
+ 10. **パスワードバリデーター**: ルールの合成
675
+
676
+ 関数型プログラミングと TDD の組み合わせにより、信頼性の高いコードを効率的に開発できます。
677
+
678
+ ## 参考コード
679
+
680
+ 本章のコード例は以下のファイルで確認できます:
681
+
682
+ - ソースコード: `apps/fsharp/part2/src/Library.fs`
683
+ - テストコード: `apps/fsharp/part2/tests/Tests.fs`
684
+
685
+ ## 次章予告
686
+
687
+ 次章から第3部「デザインパターン - 構造パターン」に入ります。Composite パターンを関数型スタイルで実装する方法を学びます。