@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,1129 @@
1
+ # Part II: 関数型スタイルのプログラミング
2
+
3
+ 本章では、関数型プログラミングの核心となるテクニックを学びます。イミュータブルなデータ操作、高階関数、そして `chain`(flatMap)による複雑なデータ変換を習得します。
4
+
5
+ ---
6
+
7
+ ## 第3章: イミュータブルなデータ操作
8
+
9
+ ### 3.1 イミュータブルとは
10
+
11
+ イミュータブル(不変)とは、一度作成されたデータが変更されないことを意味します。データを「変更」する代わりに、新しいデータを「作成」します。
12
+
13
+ ```plantuml
14
+ @startuml
15
+ !theme plain
16
+
17
+ rectangle "ミュータブル(可変)" as mut {
18
+ card "list = [A, B]" as m1
19
+ card "list.push(C)" as m2
20
+ card "list = [A, B, C]" as m3
21
+ m1 --> m2 : 変更
22
+ m2 --> m3 : 同じ配列が変わる
23
+ }
24
+
25
+ rectangle "イミュータブル(不変)" as immut {
26
+ card "list1 = [A, B]" as i1
27
+ card "list2 = [...list1, C]" as i2
28
+ card "list1 = [A, B]\nlist2 = [A, B, C]" as i3
29
+ i1 --> i2 : 新規作成
30
+ i2 --> i3 : 両方が存在
31
+ }
32
+
33
+ @enduml
34
+ ```
35
+
36
+ TypeScript では `readonly` 修飾子と fp-ts の `ReadonlyArray` モジュールを使ってイミュータブルなデータを扱います。
37
+
38
+ ### 3.2 配列の基本操作
39
+
40
+ **ソースファイル**: `app/typescript/src/ch03_immutable_data.ts`
41
+
42
+ #### appended - 要素の追加
43
+
44
+ ```typescript
45
+ // スプレッド演算子を使ったイミュータブルな追加
46
+ const appended = <T>(lst: readonly T[], element: T): readonly T[] =>
47
+ [...lst, element]
48
+
49
+ const appleBook = ['Apple', 'Book'] as const
50
+ const appleBookMango = appended(appleBook, 'Mango')
51
+
52
+ // appleBook.length === 2 // 元のリストは変わらない
53
+ // appleBookMango.length === 3 // 新しいリストが作成される
54
+ // appleBookMango === ['Apple', 'Book', 'Mango']
55
+ ```
56
+
57
+ #### slice - リストの切り出し
58
+
59
+ ```typescript
60
+ const firstTwo = <T>(lst: readonly T[]): readonly T[] =>
61
+ lst.slice(0, 2)
62
+
63
+ const lastTwo = <T>(lst: readonly T[]): readonly T[] =>
64
+ lst.slice(Math.max(0, lst.length - 2))
65
+
66
+ // firstTwo(['a', 'b', 'c']) === ['a', 'b']
67
+ // lastTwo(['a', 'b', 'c']) === ['b', 'c']
68
+ ```
69
+
70
+ ```plantuml
71
+ @startuml
72
+ !theme plain
73
+
74
+ rectangle "slice(start, end)" {
75
+ card "['a', 'b', 'c', 'd']" as orig
76
+ card "slice(1, 3)" as op
77
+ card "['b', 'c']" as result
78
+
79
+ orig --> op
80
+ op --> result
81
+ }
82
+
83
+ note bottom of result
84
+ インデックス 1 から 3 の手前まで
85
+ (end は含まない)
86
+ end note
87
+
88
+ @enduml
89
+ ```
90
+
91
+ ### 3.3 リストの変換例
92
+
93
+ **ソースファイル**: `app/typescript/src/ch03_immutable_data.ts`
94
+
95
+ ```typescript
96
+ // 最初の2要素を末尾に移動
97
+ const moveFirstTwoToEnd = <T>(lst: readonly T[]): readonly T[] => {
98
+ const firstTwo = lst.slice(0, 2)
99
+ const withoutFirstTwo = lst.slice(2)
100
+ return [...withoutFirstTwo, ...firstTwo]
101
+ }
102
+
103
+ // moveFirstTwoToEnd(['a', 'b', 'c']) === ['c', 'a', 'b']
104
+
105
+ // 最後の要素の前に挿入
106
+ const insertBeforeLast = <T>(lst: readonly T[], element: T): readonly T[] => {
107
+ if (lst.length === 0) return [element]
108
+ const last = lst.slice(lst.length - 1)
109
+ const withoutLast = lst.slice(0, lst.length - 1)
110
+ return [...withoutLast, element, ...last]
111
+ }
112
+
113
+ // insertBeforeLast(['a', 'b'], 'c') === ['a', 'c', 'b']
114
+ ```
115
+
116
+ ### 3.4 旅程の再計画
117
+
118
+ **ソースファイル**: `app/typescript/src/ch03_immutable_data.ts`
119
+
120
+ 旅行の計画変更をイミュータブルに行う例です。
121
+
122
+ ```typescript
123
+ const replan = (
124
+ plan: readonly string[],
125
+ newCity: string,
126
+ beforeCity: string
127
+ ): readonly string[] => {
128
+ const index = plan.indexOf(beforeCity)
129
+ if (index === -1) return [...plan, newCity]
130
+ return [...plan.slice(0, index), newCity, ...plan.slice(index)]
131
+ }
132
+
133
+ const planA = ['Paris', 'Berlin', 'Kraków']
134
+ const planB = replan(planA, 'Vienna', 'Kraków')
135
+
136
+ // planB === ['Paris', 'Berlin', 'Vienna', 'Kraków']
137
+ // planA === ['Paris', 'Berlin', 'Kraków'] // 元の計画は変わらない!
138
+ ```
139
+
140
+ ```plantuml
141
+ @startuml
142
+ !theme plain
143
+
144
+ rectangle "旅程の再計画" {
145
+ card "Plan A:\nParis → Berlin → Kraków" as planA
146
+ card "replan(planA, 'Vienna', 'Kraków')" as op
147
+ card "Plan B:\nParis → Berlin → Vienna → Kraków" as planB
148
+
149
+ planA --> op
150
+ op --> planB
151
+ }
152
+
153
+ note right of planA
154
+ Plan A は変更されない
155
+ (イミュータブル)
156
+ end note
157
+
158
+ @enduml
159
+ ```
160
+
161
+ ### 3.5 イミュータブルなオブジェクト
162
+
163
+ TypeScript では `readonly` 修飾子を使ってイミュータブルな型を定義します。
164
+
165
+ ```typescript
166
+ interface Point {
167
+ readonly x: number
168
+ readonly y: number
169
+ }
170
+
171
+ const createPoint = (x: number, y: number): Point => ({ x, y })
172
+
173
+ // スプレッド演算子でコピーしながら更新
174
+ const withX = (point: Point, newX: number): Point => ({ ...point, x: newX })
175
+ const withY = (point: Point, newY: number): Point => ({ ...point, y: newY })
176
+
177
+ const p1 = createPoint(1, 2)
178
+ const p2 = withX(p1, 10)
179
+
180
+ // p1.x === 1 // 元のPointは変わらない
181
+ // p2.x === 10
182
+ // p2.y === 2
183
+ ```
184
+
185
+ ### 3.6 fp-ts を使ったイミュータブル操作
186
+
187
+ fp-ts の `ReadonlyArray` モジュールを使うと、より型安全にイミュータブル操作ができます。
188
+
189
+ ```typescript
190
+ import { pipe } from 'fp-ts/function'
191
+ import * as RA from 'fp-ts/ReadonlyArray'
192
+
193
+ // append - 要素を追加
194
+ const appendWithFpts = <T>(lst: readonly T[], element: T): readonly T[] =>
195
+ pipe(lst, RA.append(element))
196
+
197
+ // prepend - 先頭に追加
198
+ const prependWithFpts = <T>(lst: readonly T[], element: T): readonly T[] =>
199
+ pipe(lst, RA.prepend(element))
200
+
201
+ // concat - 連結
202
+ const concatWithFpts = <T>(
203
+ lst1: readonly T[],
204
+ lst2: readonly T[]
205
+ ): readonly T[] =>
206
+ pipe(lst1, RA.concat(lst2))
207
+ ```
208
+
209
+ ---
210
+
211
+ ## 第4章: 関数を値として扱う
212
+
213
+ ### 4.1 高階関数とは
214
+
215
+ 高階関数(Higher-Order Function)とは、以下のいずれかを満たす関数です:
216
+
217
+ 1. 関数を引数として受け取る
218
+ 2. 関数を戻り値として返す
219
+
220
+ ```plantuml
221
+ @startuml
222
+ !theme plain
223
+
224
+ rectangle "高階関数" {
225
+ rectangle "関数を引数に取る" as arg {
226
+ card "sortBy(wordScore)" as sortBy
227
+ card "map(transform)" as map
228
+ card "filter(predicate)" as filter
229
+ }
230
+
231
+ rectangle "関数を返す" as ret {
232
+ card "largerThan(n)" as larger
233
+ card "divisibleBy(n)" as divisible
234
+ }
235
+ }
236
+
237
+ @enduml
238
+ ```
239
+
240
+ ### 4.2 関数を引数として渡す
241
+
242
+ **ソースファイル**: `app/typescript/src/ch04_higher_order.ts`
243
+
244
+ #### sortBy - ソート基準を関数で指定
245
+
246
+ fp-ts の `Ord` を使って型安全にソートできます。
247
+
248
+ ```typescript
249
+ import { pipe } from 'fp-ts/function'
250
+ import * as RA from 'fp-ts/ReadonlyArray'
251
+ import * as Ord from 'fp-ts/Ord'
252
+ import * as N from 'fp-ts/number'
253
+
254
+ const score = (word: string): number => word.replaceAll('a', '').length
255
+
256
+ // 任意のスコア関数でソート(降順)
257
+ const rankedWords = (
258
+ words: readonly string[],
259
+ wordScore: (word: string) => number
260
+ ): readonly string[] =>
261
+ pipe(
262
+ words,
263
+ RA.sortBy([Ord.reverse(Ord.contramap(wordScore)(N.Ord))])
264
+ )
265
+
266
+ const words = ['rust', 'java']
267
+ const sortedWords = rankedWords(words, score)
268
+ // sortedWords === ['rust', 'java']
269
+ // rust: 4文字 (r, u, s, t), java: 2文字 (j, v)
270
+ ```
271
+
272
+ ```plantuml
273
+ @startuml
274
+ !theme plain
275
+
276
+ rectangle "sortBy の動作" {
277
+ card "['rust', 'java']" as input
278
+ card "score('rust') = 4\nscore('java') = 2" as scores
279
+ card "['rust', 'java']" as output
280
+
281
+ input --> scores : score関数を適用
282
+ scores --> output : スコア順にソート
283
+ }
284
+
285
+ @enduml
286
+ ```
287
+
288
+ #### map - 各要素を変換
289
+
290
+ ```typescript
291
+ const getLengths = (words: readonly string[]): readonly number[] =>
292
+ pipe(
293
+ words,
294
+ RA.map((w) => w.length)
295
+ )
296
+
297
+ // getLengths(['scala', 'rust', 'ada']) === [5, 4, 3]
298
+
299
+ const doubleAll = (numbers: readonly number[]): readonly number[] =>
300
+ pipe(
301
+ numbers,
302
+ RA.map((n) => n * 2)
303
+ )
304
+
305
+ // doubleAll([5, 1, 2, 4, 0]) === [10, 2, 4, 8, 0]
306
+ ```
307
+
308
+ ```plantuml
309
+ @startuml
310
+ !theme plain
311
+
312
+ rectangle "map の動作" {
313
+ card "['scala', 'rust', 'ada']" as input
314
+ card "length関数を各要素に適用" as op
315
+ card "[5, 4, 3]" as output
316
+
317
+ input --> op
318
+ op --> output
319
+ }
320
+
321
+ @enduml
322
+ ```
323
+
324
+ #### filter - 条件に合う要素を抽出
325
+
326
+ ```typescript
327
+ const filterOdd = (numbers: readonly number[]): readonly number[] =>
328
+ pipe(
329
+ numbers,
330
+ RA.filter((n) => n % 2 === 1)
331
+ )
332
+
333
+ // filterOdd([5, 1, 2, 4, 0]) === [5, 1]
334
+
335
+ const filterLargerThan = (
336
+ numbers: readonly number[],
337
+ threshold: number
338
+ ): readonly number[] =>
339
+ pipe(
340
+ numbers,
341
+ RA.filter((n) => n > threshold)
342
+ )
343
+
344
+ // filterLargerThan([5, 1, 2, 4, 0], 4) === [5]
345
+ ```
346
+
347
+ #### reduce - 畳み込み
348
+
349
+ ```typescript
350
+ const sumAll = (numbers: readonly number[]): number =>
351
+ pipe(
352
+ numbers,
353
+ RA.reduce(0, (acc, n) => acc + n)
354
+ )
355
+
356
+ // sumAll([5, 1, 2, 4, 100]) === 112
357
+
358
+ const findMax = (numbers: readonly number[]): number | undefined =>
359
+ pipe(
360
+ numbers,
361
+ RA.reduce(undefined as number | undefined, (max, n) =>
362
+ max === undefined || n > max ? n : max
363
+ )
364
+ )
365
+
366
+ // findMax([5, 1, 2, 4, 15]) === 15
367
+ ```
368
+
369
+ ```plantuml
370
+ @startuml
371
+ !theme plain
372
+
373
+ rectangle "reduce の動作" {
374
+ card "初期値: 0" as init
375
+ card "0 + 5 = 5" as s1
376
+ card "5 + 1 = 6" as s2
377
+ card "6 + 2 = 8" as s3
378
+ card "8 + 4 = 12" as s4
379
+ card "12 + 100 = 112" as s5
380
+
381
+ init --> s1
382
+ s1 --> s2
383
+ s2 --> s3
384
+ s3 --> s4
385
+ s4 --> s5
386
+ }
387
+
388
+ @enduml
389
+ ```
390
+
391
+ ### 4.3 型とインターフェース
392
+
393
+ **ソースファイル**: `app/typescript/src/ch04_higher_order.ts`
394
+
395
+ ```typescript
396
+ interface ProgrammingLanguage {
397
+ readonly name: string
398
+ readonly year: number
399
+ }
400
+
401
+ const createLanguage = (name: string, year: number): ProgrammingLanguage =>
402
+ ({ name, year })
403
+
404
+ const java = createLanguage('Java', 1995)
405
+ const scala = createLanguage('Scala', 2004)
406
+ const languages = [java, scala]
407
+
408
+ // フィールドにアクセス
409
+ const getNames = (langs: readonly ProgrammingLanguage[]): readonly string[] =>
410
+ pipe(
411
+ langs,
412
+ RA.map((lang) => lang.name)
413
+ )
414
+
415
+ // getNames(languages) === ['Java', 'Scala']
416
+
417
+ // 条件でフィルタ
418
+ const filterYoungLanguages = (
419
+ langs: readonly ProgrammingLanguage[],
420
+ afterYear: number
421
+ ): readonly ProgrammingLanguage[] =>
422
+ pipe(
423
+ langs,
424
+ RA.filter((lang) => lang.year > afterYear)
425
+ )
426
+
427
+ // filterYoungLanguages(languages, 2000) === [scala]
428
+ ```
429
+
430
+ ### 4.4 関数を返す関数
431
+
432
+ **ソースファイル**: `app/typescript/src/ch04_higher_order.ts`
433
+
434
+ ```typescript
435
+ const largerThan = (n: number): ((i: number) => boolean) => (i) => i > n
436
+
437
+ // 使用例
438
+ pipe([5, 1, 2, 4, 0], RA.filter(largerThan(4)))
439
+ // => [5]
440
+
441
+ pipe([5, 1, 2, 4, 0], RA.filter(largerThan(1)))
442
+ // => [5, 2, 4]
443
+ ```
444
+
445
+ ```plantuml
446
+ @startuml
447
+ !theme plain
448
+
449
+ rectangle "関数を返す関数" {
450
+ card "largerThan(4)" as call
451
+ card "(i) => i > 4" as fn
452
+ card "filter に渡す" as filter
453
+
454
+ call --> fn : 関数を生成
455
+ fn --> filter : 生成された関数を使用
456
+ }
457
+
458
+ note bottom
459
+ largerThan(4) は
460
+ 「4より大きいか判定する関数」を返す
461
+ end note
462
+
463
+ @enduml
464
+ ```
465
+
466
+ ### 4.5 カリー化
467
+
468
+ カリー化(Currying)は、複数の引数を取る関数を、引数を1つずつ取る関数のチェーンに変換する技法です。
469
+
470
+ ```typescript
471
+ // 通常の関数
472
+ const largerThanNormal = (n: number, i: number): boolean => i > n
473
+
474
+ // カリー化された関数
475
+ const largerThan = (n: number) => (i: number): boolean => i > n
476
+
477
+ // 使用例
478
+ const isLargerThan4 = largerThan(4) // 部分適用
479
+ isLargerThan4(5) // => true
480
+ isLargerThan4(3) // => false
481
+
482
+ // filter に直接渡す
483
+ pipe([5, 1, 2, 4, 0], RA.filter(largerThan(4)))
484
+ // => [5]
485
+ ```
486
+
487
+ ```plantuml
488
+ @startuml
489
+ !theme plain
490
+
491
+ rectangle "カリー化" {
492
+ rectangle "通常の関数" as normal {
493
+ card "f(a, b, c)" as n1
494
+ }
495
+
496
+ rectangle "カリー化された関数" as curried {
497
+ card "f(a)(b)(c)" as c1
498
+ }
499
+
500
+ normal --> curried : カリー化
501
+ }
502
+
503
+ note bottom of curried
504
+ 部分適用が可能
505
+ f(a) → 関数を返す
506
+ f(a)(b) → 関数を返す
507
+ f(a)(b)(c) → 結果を返す
508
+ end note
509
+
510
+ @enduml
511
+ ```
512
+
513
+ ### 4.6 ワードスコアリングの例
514
+
515
+ **ソースファイル**: `app/typescript/src/ch04_higher_order.ts`
516
+
517
+ 複数のスコアリングロジックを組み合わせる例です。
518
+
519
+ ```typescript
520
+ const score = (word: string): number => word.replaceAll('a', '').length
521
+ const bonus = (word: string): number => (word.includes('c') ? 5 : 0)
522
+ const penalty = (word: string): number => (word.includes('s') ? 7 : 0)
523
+
524
+ // カリー化された高スコア単語フィルタ
525
+ const highScoringWordsWithThreshold =
526
+ (wordScoreFn: (word: string) => number) =>
527
+ (higherThan: number) =>
528
+ (words: readonly string[]): readonly string[] =>
529
+ pipe(
530
+ words,
531
+ RA.filter((word) => wordScoreFn(word) > higherThan)
532
+ )
533
+
534
+ const words = ['ada', 'haskell', 'scala', 'java', 'rust']
535
+ const scorer = highScoringWordsWithThreshold(wordScoreWithBonusAndPenalty)
536
+
537
+ scorer(1)(words)
538
+ // => ['java']
539
+
540
+ scorer(0)(words)
541
+ // => ['ada', 'scala', 'java']
542
+ ```
543
+
544
+ ---
545
+
546
+ ## 第5章: chain(flatMap)とネスト構造
547
+
548
+ ### 5.1 flatten と flatMap
549
+
550
+ **ソースファイル**: `app/typescript/src/ch05_flatmap.ts`
551
+
552
+ #### flatten - ネストしたリストを平坦化
553
+
554
+ ```typescript
555
+ import { pipe } from 'fp-ts/function'
556
+ import * as RA from 'fp-ts/ReadonlyArray'
557
+
558
+ interface Book {
559
+ readonly title: string
560
+ readonly authors: readonly string[]
561
+ }
562
+
563
+ const books: readonly Book[] = [
564
+ { title: 'FP in Scala', authors: ['Chiusano', 'Bjarnason'] },
565
+ { title: 'The Hobbit', authors: ['Tolkien'] },
566
+ ]
567
+
568
+ // map だけだとネストする
569
+ const authorLists = pipe(books, RA.map((book) => book.authors))
570
+ // [['Chiusano', 'Bjarnason'], ['Tolkien']]
571
+
572
+ // flatten で平坦化
573
+ const authors = pipe(authorLists, RA.flatten)
574
+ // ['Chiusano', 'Bjarnason', 'Tolkien']
575
+ ```
576
+
577
+ ```plantuml
578
+ @startuml
579
+ !theme plain
580
+
581
+ rectangle "flatten の動作" {
582
+ card "[['A', 'B'], ['C']]" as nested
583
+ card "flatten" as op
584
+ card "['A', 'B', 'C']" as flat
585
+
586
+ nested --> op
587
+ op --> flat
588
+ }
589
+
590
+ @enduml
591
+ ```
592
+
593
+ #### chain = map + flatten
594
+
595
+ fp-ts では `flatMap` は `chain` という名前で提供されています。
596
+
597
+ ```typescript
598
+ // map して flatten
599
+ const authors1 = pipe(
600
+ books,
601
+ RA.map((book) => book.authors),
602
+ RA.flatten
603
+ )
604
+
605
+ // chain で同じことを1行で
606
+ const authors2 = pipe(
607
+ books,
608
+ RA.chain((book) => book.authors)
609
+ )
610
+
611
+ // authors1 === authors2
612
+ // ['Chiusano', 'Bjarnason', 'Tolkien']
613
+ ```
614
+
615
+ ### 5.2 chain によるリストサイズの変化
616
+
617
+ ```typescript
618
+ // 要素数が増える
619
+ pipe([1, 2, 3], RA.chain((i) => [i, i + 10]))
620
+ // [1, 11, 2, 12, 3, 13] - 6要素
621
+
622
+ // 要素数が同じ
623
+ pipe([1, 2, 3], RA.chain((i) => [i * 2]))
624
+ // [2, 4, 6] - 3要素
625
+
626
+ // 要素数が減る(フィルタリング効果)
627
+ pipe([1, 2, 3], RA.chain((i) => (i % 2 === 0 ? [i] : [])))
628
+ // [2] - 1要素
629
+ ```
630
+
631
+ ```plantuml
632
+ @startuml
633
+ !theme plain
634
+
635
+ rectangle "chain とサイズの変化" {
636
+ rectangle "増加" as inc {
637
+ card "[1, 2, 3]" as i1
638
+ card "i => [i, i+10]" as f1
639
+ card "[1, 11, 2, 12, 3, 13]" as r1
640
+ i1 --> f1
641
+ f1 --> r1
642
+ }
643
+
644
+ rectangle "減少(フィルタ)" as dec {
645
+ card "[1, 2, 3]" as i2
646
+ card "i => if even [i] else []" as f2
647
+ card "[2]" as r2
648
+ i2 --> f2
649
+ f2 --> r2
650
+ }
651
+ }
652
+
653
+ @enduml
654
+ ```
655
+
656
+ ### 5.3 ネストした chain
657
+
658
+ 複数のリストを組み合わせる場合、chain をネストします。
659
+
660
+ ```typescript
661
+ interface Book {
662
+ readonly title: string
663
+ readonly authors: readonly string[]
664
+ }
665
+
666
+ interface Movie {
667
+ readonly title: string
668
+ }
669
+
670
+ const bookAdaptations = (author: string): readonly Movie[] => {
671
+ if (author === 'Tolkien') {
672
+ return [
673
+ { title: 'An Unexpected Journey' },
674
+ { title: 'The Desolation of Smaug' },
675
+ ]
676
+ }
677
+ return []
678
+ }
679
+
680
+ const books: readonly Book[] = [
681
+ { title: 'FP in Scala', authors: ['Chiusano', 'Bjarnason'] },
682
+ { title: 'The Hobbit', authors: ['Tolkien'] },
683
+ ]
684
+
685
+ // ネストした chain
686
+ const recommendations = pipe(
687
+ books,
688
+ RA.chain((book) =>
689
+ pipe(
690
+ book.authors,
691
+ RA.chain((author) =>
692
+ pipe(
693
+ bookAdaptations(author),
694
+ RA.map(
695
+ (movie) =>
696
+ `You may like ${movie.title}, because you liked ${author}'s ${book.title}`
697
+ )
698
+ )
699
+ )
700
+ )
701
+ )
702
+ )
703
+
704
+ // 結果:
705
+ // [
706
+ // "You may like An Unexpected Journey, because you liked Tolkien's The Hobbit",
707
+ // "You may like The Desolation of Smaug, because you liked Tolkien's The Hobbit"
708
+ // ]
709
+ ```
710
+
711
+ ```plantuml
712
+ @startuml
713
+ !theme plain
714
+
715
+ rectangle "ネストした chain のフロー" {
716
+ card "books" as books
717
+ card "book.authors" as authors
718
+ card "bookAdaptations(author)" as movies
719
+ card "recommendation string" as result
720
+
721
+ books --> authors : chain
722
+ authors --> movies : chain
723
+ movies --> result : map
724
+ }
725
+
726
+ note bottom
727
+ 最後だけ map
728
+ 途中は chain
729
+ end note
730
+
731
+ @enduml
732
+ ```
733
+
734
+ ### 5.4 Point の生成例
735
+
736
+ **ソースファイル**: `app/typescript/src/ch05_flatmap.ts`
737
+
738
+ ```typescript
739
+ interface Point {
740
+ readonly x: number
741
+ readonly y: number
742
+ }
743
+
744
+ const createPoint = (x: number, y: number): Point => ({ x, y })
745
+
746
+ // 全ての (x, y) の組み合わせから Point を生成
747
+ const generatePoints = (
748
+ xs: readonly number[],
749
+ ys: readonly number[]
750
+ ): readonly Point[] =>
751
+ pipe(
752
+ xs,
753
+ RA.chain((x) =>
754
+ pipe(
755
+ ys,
756
+ RA.map((y) => createPoint(x, y))
757
+ )
758
+ )
759
+ )
760
+
761
+ generatePoints([1], [-2, 7])
762
+ // [{ x: 1, y: -2 }, { x: 1, y: 7 }]
763
+
764
+ generatePoints([1, 2], [-2, 7])
765
+ // [{ x: 1, y: -2 }, { x: 1, y: 7 }, { x: 2, y: -2 }, { x: 2, y: 7 }]
766
+ ```
767
+
768
+ ### 5.5 Option との組み合わせ
769
+
770
+ **ソースファイル**: `app/typescript/src/ch05_flatmap.ts`
771
+
772
+ fp-ts の `Option` 型と組み合わせることで、安全なデータ変換ができます。
773
+
774
+ ```typescript
775
+ import * as O from 'fp-ts/Option'
776
+
777
+ // Option のリストから Some の値だけを取り出す
778
+ const compactOptions = <T>(options: readonly O.Option<T>[]): readonly T[] =>
779
+ pipe(options, RA.compact)
780
+
781
+ compactOptions([O.some(1), O.none, O.some(2), O.none, O.some(3)])
782
+ // [1, 2, 3]
783
+
784
+ // filterMap - map と filter を同時に
785
+ const filterMapExample = <T, U>(
786
+ func: (item: T) => O.Option<U>,
787
+ lst: readonly T[]
788
+ ): readonly U[] =>
789
+ pipe(lst, RA.filterMap(func))
790
+
791
+ filterMapExample(
792
+ (s: string) => (s.length > 2 ? O.some(s.toUpperCase()) : O.none),
793
+ ['a', 'abc', 'de', 'xyz']
794
+ )
795
+ // ['ABC', 'XYZ']
796
+ ```
797
+
798
+ ### 5.6 traverse - 効果の反転
799
+
800
+ **ソースファイル**: `app/typescript/src/ch05_flatmap.ts`
801
+
802
+ `traverse` は、リストの各要素に `Option` を返す関数を適用し、全てが `Some` なら `Some<配列>` を返し、一つでも `None` なら `None` を返します。
803
+
804
+ ```typescript
805
+ const traverseOption = <T, U>(
806
+ func: (item: T) => O.Option<U>,
807
+ lst: readonly T[]
808
+ ): O.Option<readonly U[]> =>
809
+ pipe(lst, RA.traverse(O.Applicative)(func))
810
+
811
+ const safeDivide = (n: number): O.Option<number> =>
812
+ n === 0 ? O.none : O.some(10 / n)
813
+
814
+ traverseOption(safeDivide, [1, 2, 5])
815
+ // some([10, 5, 2])
816
+
817
+ traverseOption(safeDivide, [1, 0, 5])
818
+ // none - 0で割る要素があるため全体が失敗
819
+ ```
820
+
821
+ ### 5.7 円内の点の判定
822
+
823
+ **ソースファイル**: `app/typescript/src/ch05_flatmap.ts`
824
+
825
+ chain でフィルタリングも行う例です。
826
+
827
+ ```typescript
828
+ interface Point {
829
+ readonly x: number
830
+ readonly y: number
831
+ }
832
+
833
+ const points: readonly Point[] = [
834
+ { x: 5, y: 2 },
835
+ { x: 1, y: 1 },
836
+ ]
837
+ const radiuses = [2, 1]
838
+
839
+ const isInside = (point: Point, radius: number): boolean =>
840
+ radius * radius >= point.x * point.x + point.y * point.y
841
+
842
+ // 全組み合わせを生成
843
+ const allCombinations = (
844
+ points: readonly Point[],
845
+ radiuses: readonly number[]
846
+ ): readonly string[] =>
847
+ pipe(
848
+ radiuses,
849
+ RA.chain((r) =>
850
+ pipe(
851
+ points,
852
+ RA.map(
853
+ (point) =>
854
+ `Point(${point.x},${point.y}) is within a radius of ${r}: ${isInside(point, r)}`
855
+ )
856
+ )
857
+ )
858
+ )
859
+
860
+ // 結果:
861
+ // [
862
+ // "Point(5,2) is within a radius of 2: false",
863
+ // "Point(1,1) is within a radius of 2: true",
864
+ // "Point(5,2) is within a radius of 1: false",
865
+ // "Point(1,1) is within a radius of 1: false"
866
+ // ]
867
+ ```
868
+
869
+ #### chain によるフィルタリング
870
+
871
+ ```typescript
872
+ // 円内の点のみを抽出
873
+ const insidePoints = (
874
+ points: readonly Point[],
875
+ radiuses: readonly number[]
876
+ ): readonly string[] =>
877
+ pipe(
878
+ radiuses,
879
+ RA.chain((r) =>
880
+ pipe(
881
+ points,
882
+ RA.filter((point) => isInside(point, r)),
883
+ RA.map(
884
+ (point) => `Point(${point.x},${point.y}) is within a radius of ${r}`
885
+ )
886
+ )
887
+ )
888
+ )
889
+
890
+ // 結果: ["Point(1,1) is within a radius of 2"]
891
+ ```
892
+
893
+ ```plantuml
894
+ @startuml
895
+ !theme plain
896
+
897
+ rectangle "フィルタリングの3つの方法" {
898
+ rectangle "1. filter を使う" as m1 {
899
+ card "RA.filter((p) => isInside(p, r))"
900
+ }
901
+
902
+ rectangle "2. chain でフィルタ" as m2 {
903
+ card "RA.chain((p) => isInside(p, r) ? [p] : [])"
904
+ }
905
+
906
+ rectangle "3. filterMap を使う" as m3 {
907
+ card "RA.filterMap((p) =>\n isInside(p, r) ? O.some(p) : O.none)"
908
+ }
909
+ }
910
+
911
+ @enduml
912
+ ```
913
+
914
+ ---
915
+
916
+ ## まとめ
917
+
918
+ ### Part II で学んだこと
919
+
920
+ ```plantuml
921
+ @startuml
922
+ !theme plain
923
+
924
+ rectangle "Part II: 関数型スタイルのプログラミング" {
925
+ rectangle "第3章" as ch3 {
926
+ card "イミュータブルデータ"
927
+ card "slice / spread"
928
+ card "ReadonlyArray"
929
+ }
930
+
931
+ rectangle "第4章" as ch4 {
932
+ card "高階関数"
933
+ card "map / filter / reduce"
934
+ card "関数を返す関数"
935
+ card "カリー化"
936
+ card "Ord によるソート"
937
+ }
938
+
939
+ rectangle "第5章" as ch5 {
940
+ card "flatten / chain"
941
+ card "ネストした変換"
942
+ card "Option との組み合わせ"
943
+ card "traverse"
944
+ }
945
+ }
946
+
947
+ ch3 --> ch4
948
+ ch4 --> ch5
949
+
950
+ @enduml
951
+ ```
952
+
953
+ ### キーポイント
954
+
955
+ | 章 | 主要概念 | キー操作 |
956
+ |----|----------|----------|
957
+ | 第3章 | イミュータブル | `slice`, スプレッド演算子, `readonly` |
958
+ | 第4章 | 高階関数 | `RA.map`, `RA.filter`, `RA.reduce`, `RA.sortBy` |
959
+ | 第5章 | 平坦化 | `RA.flatten`, `RA.chain`, `RA.traverse` |
960
+
961
+ ### Scala vs TypeScript fp-ts 比較
962
+
963
+ | Scala | TypeScript (fp-ts) | 説明 |
964
+ |-------|-------------------|------|
965
+ | `list.appended(x)` | `[...list, x]` | 末尾に追加 |
966
+ | `list.slice(a, b)` | `list.slice(a, b)` | スライス |
967
+ | `list.map(f)` | `pipe(list, RA.map(f))` | map |
968
+ | `list.filter(p)` | `pipe(list, RA.filter(p))` | filter |
969
+ | `list.foldLeft(z)(f)` | `pipe(list, RA.reduce(z, f))` | reduce |
970
+ | `list.flatMap(f)` | `pipe(list, RA.chain(f))` | flatMap |
971
+ | `list.flatten` | `pipe(list, RA.flatten)` | flatten |
972
+ | `list.sortBy(f)` | `pipe(list, RA.sortBy([ord]))` | sortBy |
973
+
974
+ ### 重要な法則
975
+
976
+ 1. **イミュータブルデータ**: 元のデータは変更せず、新しいデータを作成する
977
+ 2. **関数は値**: 関数を引数として渡したり、戻り値として返したりできる
978
+ 3. **chain パターン**: ネストした構造を平坦化しながら変換する
979
+ 4. **traverse パターン**: 効果(Option等)を反転させてリスト全体を扱う
980
+
981
+ ### 次のステップ
982
+
983
+ Part III では、以下のトピックを学びます:
984
+
985
+ - `Option` 型による安全なエラーハンドリング
986
+ - `Either` 型と複合的なエラー処理
987
+ - エラー処理のパターン
988
+
989
+ ---
990
+
991
+ ## 演習問題
992
+
993
+ ### 問題 1: イミュータブルな操作
994
+
995
+ 以下の関数を実装してください。リストの中央に要素を挿入する関数です。
996
+
997
+ ```typescript
998
+ const insertAtMiddle = <T>(list: readonly T[], element: T): readonly T[] => ???
999
+
1000
+ // 期待される動作
1001
+ // insertAtMiddle(['a', 'b', 'c', 'd'], 'X') === ['a', 'b', 'X', 'c', 'd']
1002
+ // insertAtMiddle(['a', 'b'], 'X') === ['a', 'X', 'b']
1003
+ ```
1004
+
1005
+ <details>
1006
+ <summary>解答</summary>
1007
+
1008
+ ```typescript
1009
+ const insertAtMiddle = <T>(list: readonly T[], element: T): readonly T[] => {
1010
+ const middle = Math.floor(list.length / 2)
1011
+ const before = list.slice(0, middle)
1012
+ const after = list.slice(middle)
1013
+ return [...before, element, ...after]
1014
+ }
1015
+ ```
1016
+
1017
+ </details>
1018
+
1019
+ ### 問題 2: 高階関数
1020
+
1021
+ 以下の関数を実装してください。条件を満たす要素の数をカウントする関数です。
1022
+
1023
+ ```typescript
1024
+ const countWhere = <T>(
1025
+ list: readonly T[],
1026
+ predicate: (item: T) => boolean
1027
+ ): number => ???
1028
+
1029
+ // 期待される動作
1030
+ // countWhere([1, 2, 3, 4, 5], (i) => i > 3) === 2
1031
+ // countWhere(['a', 'bb', 'ccc'], (s) => s.length > 1) === 2
1032
+ ```
1033
+
1034
+ <details>
1035
+ <summary>解答</summary>
1036
+
1037
+ ```typescript
1038
+ import { pipe } from 'fp-ts/function'
1039
+ import * as RA from 'fp-ts/ReadonlyArray'
1040
+
1041
+ const countWhere = <T>(
1042
+ list: readonly T[],
1043
+ predicate: (item: T) => boolean
1044
+ ): number =>
1045
+ pipe(
1046
+ list,
1047
+ RA.filter(predicate),
1048
+ (filtered) => filtered.length
1049
+ )
1050
+
1051
+ // または reduce を使って
1052
+ const countWhere2 = <T>(
1053
+ list: readonly T[],
1054
+ predicate: (item: T) => boolean
1055
+ ): number =>
1056
+ pipe(
1057
+ list,
1058
+ RA.reduce(0, (count, elem) => (predicate(elem) ? count + 1 : count))
1059
+ )
1060
+ ```
1061
+
1062
+ </details>
1063
+
1064
+ ### 問題 3: chain の活用
1065
+
1066
+ 以下のネストした配列を chain で平坦化してください。
1067
+
1068
+ ```typescript
1069
+ const nested = [[1, 2], [10, 20], [100, 200]]
1070
+ // それぞれの配列の各要素を足し合わせた全ての組み合わせを生成
1071
+ // 期待される結果: [111, 211, 121, 221, 112, 212, 122, 222]
1072
+ ```
1073
+
1074
+ <details>
1075
+ <summary>解答</summary>
1076
+
1077
+ ```typescript
1078
+ import { pipe } from 'fp-ts/function'
1079
+ import * as RA from 'fp-ts/ReadonlyArray'
1080
+
1081
+ const result = pipe(
1082
+ [1, 2],
1083
+ RA.chain((x) =>
1084
+ pipe(
1085
+ [10, 20],
1086
+ RA.chain((y) =>
1087
+ pipe(
1088
+ [100, 200],
1089
+ RA.map((z) => x + y + z)
1090
+ )
1091
+ )
1092
+ )
1093
+ )
1094
+ )
1095
+
1096
+ // 結果: [111, 211, 121, 221, 112, 212, 122, 222]
1097
+ ```
1098
+
1099
+ </details>
1100
+
1101
+ ### 問題 4: chain によるフィルタリング
1102
+
1103
+ filter を使わずに、chain だけで偶数のみを抽出するコードを書いてください。
1104
+
1105
+ ```typescript
1106
+ const numbers = [1, 2, 3, 4, 5, 6]
1107
+ // 偶数のみを抽出: [2, 4, 6]
1108
+ ```
1109
+
1110
+ <details>
1111
+ <summary>解答</summary>
1112
+
1113
+ ```typescript
1114
+ import { pipe } from 'fp-ts/function'
1115
+ import * as RA from 'fp-ts/ReadonlyArray'
1116
+
1117
+ const evenNumbers = pipe(
1118
+ numbers,
1119
+ RA.chain((n) => (n % 2 === 0 ? [n] : []))
1120
+ )
1121
+
1122
+ // または関数に分離
1123
+ const evenFilter = (n: number): readonly number[] =>
1124
+ n % 2 === 0 ? [n] : []
1125
+
1126
+ const evenNumbers2 = pipe(numbers, RA.chain(evenFilter))
1127
+ ```
1128
+
1129
+ </details>