The Ask
❯ I wonder if it is worthwile extracting functions from Site.hs to one or more Haskell modules for clarity of purpose and maintainability.
The function main :: IO () , which is quite long, should remain in Site.hs . What do you think?
⏺ That’s a reasonable refactoring to consider. Site.hs is quite large (~1000 lines) and contains several distinct concerns:
Potential modules:
┌───────────────┬─────────────────────────────────────────────────────────────────────────────────────────┐
│ Module │ Contents │
├───────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ Utils.hs │ escapeHtmlAttr, stripHtmlTags, monthName, trim, toSlug, etc. │
├───────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ Archive.hs │ scanArchiveForPosts, scanArchiveForTag, extractContentTags, findTxtFiles, buildTagIndex │
├───────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ Context.hs │ postCtx, archivePostCtx, noteCtx, combinedPostCtx and variants │
├───────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ Compilers.hs │ txtCompiler, scriptaCompiler, txtPostCompiler, txtTagCompiler │
├───────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ Routes.hs │ archiveToPostRoute, archiveToDiaryRoute, etc. │
├───────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤
│ Navigation.hs │ buildPostNavMap, buildNoteNavMap, buildLinkMap │
└───────────────┴─────────────────────────────────────────────────────────────────────────────────────────┘
Pros:
- Clearer separation of concerns
- Easier to find and modify specific functionality
- Better testability (if you add tests later)
Cons:
- More files to navigate
- Some coupling exists (contexts use compilers, routes need maps)
- Refactoring effort for a working system
My recommendation: It’s worthwhile if you’re actively developing the site. Start with the lowest-hanging fruit - Utils.hs has no dependencies on other site
code. Archive.hs is also fairly self-contained.
Would you like me to do this refactoring?
❯ Let’s do Utils.hs and Archive.hs
The Result
Done! Successfully extracted to two new modules:
Utils.hs (pure utility functions):
- escapeHtmlAttr, getModTime, stripHtmlTags
- monthName, takeBaseName’, formatZettelDate
- extractFirstLineTitle, toSlug
- stripFirstLine, stripFirstLineTags
Archive.hs (archive scanning/processing):
- findTxtFiles, findMdFiles
- hasPostTag, hasTag, extractPostCategory
- extractContentTags, scanArchiveForPosts
- scanArchiveForTag, scanArchiveForContentTags
- buildTagIndex, preprocessScriptaImport
Site.hs is now ~650 lines (down from ~1040), focusing on:
- main (Hakyll rules)
- Context builders
- Compilers
- Route functions
- Navigation map builders
✻ Baked for 4m 20s