Functional programmingÂ
Phase 1: The Brain Rewire (2–3 Weeks)
The Tool: Haskell
The Goal: Force your brain to solve problems without variable mutations, for loops, or try/catch statements.
-
What to do: Read the first 7 chapters of the free book Learn You a Haskell for Great Good!. Download GHCUp (the Haskell installer), open the interactive terminal (ghci), and write code.
-
Key Milestones to Reach:
-
Learn to process lists using Recursion instead of loops.
-
Master Pattern Matching to handle control flow.
-
Understand Currying & Higher-Order Functions (passing functions into functions).
-
Why this step is mandatory: You will try to “cheat” using imperative code. Haskell’s compiler will block you, forcing your brain to adapt to pure functional thinking.
Phase 2: The Mental Bridge (1–2 Weeks)
The Tool: The Scala “Red Book”
The Goal: Learn how to design a real application using these strict rules. You do not need to write Scala code here; treat this as a conceptual reading assignment.
-
What to do: Read Chapters 1 through 6 of Functional Programming in Scala (2nd Edition).
-
Key Milestones to Reach:
-
Understand how functional data structures work.
-
Learn how to handle errors beautifully using Option and Either instead of throwing exceptions.
-
Understand how to handle side effects (like database calls or random numbers) purely.
Phase 3: The Homecoming (Ongoing)
The Tool: TypeScript + Effect (@effect/io)
The Goal: Bring your new mindset back to your day job.
-
What to do: Put away Haskell and Scala. Go straight to the official Effect Website Documentation and complete their getting started guides.
-
Why Effect?: In the TypeScript ecosystem, fp-ts is deprecated and outdated. Effect is the modern, industry-standard ecosystem for pure FP in TypeScript. It gives you the exact power of Haskell/Scala but runs natively in Node.js and the browser.
-
Key Milestones to Reach:
-
Replace try/catch blocks with type-safe Effect.fail.
-
Manage asynchronous code natively using the unified Effect type instead of raw Promises.
-
Track your errors and dependencies explicitly in your TypeScript types.