SM's Haskell notes: **Haskell | [[Haskell map]] | [[Haskell minimap]] | [[Haskell games]]** Last updated: 2025-08-06 A fine programming language. https://en.wikipedia.org/wiki/Haskell ## Projects Some Haskell-related services I operate: - [[Haskell map]] - an efficient overview of Haskell learning resources and web presence - https://haskell-links.org - a search UI for \#haskell's lambdabot links database - https://haskell-status.org - accurate uptime info for Haskell ecosystem services - https://matrix.to/#/#haskell-space:matrix.org - Haskell's matrix chat presence (one of the main admins) - [[Haskell games]] - a games list / mini FAQ Past: - [Haskell Tiny Game Jam](https://github.com/haskell-game/tiny-games-hs) - 2023 game programming contest with 55 entries and 109 reviews - hackagebot - a reliable bot announcing Hackage uploads in the \#haskell IRC channel Some other Haskell-based projects: - https://hledger.org - plain text accounting app - https://hub.darcs.net & [darcsden](https://hub.darcs.net/simon/darcsden) - code forge for the darcs version control system (maintainer) - https://github.com/simonmichael/quickbench benchmarking tool - https://github.com/simonmichael/shelltestrunner test tool - https://github.com/simonmichael/games/tree/main/caverunner terminal game with sound, high scores - https://github.com/haskell-game/fungen the original Haskell game engine (maintainer) - https://hub.darcs.net/simon/rss2irc feed-announcing IRC bot (maintainer) ## FAQ ### What is Haskell good for ? It's good when you want to design and build software that's correct, robust, and long-term maintainable. It's also very good for writing concurrent software. Haskell software also is usually pretty fast, quick-starting, and portable. How could we [describe Haskell's killer domain in a few words](https://news.ycombinator.com/item?id=44019245) ? \ "High-assurance applications and prototyping/research." Or in more words ? > Q: very vague and common question but like in general, what is haskell specialized for? Like C and Rust are good for systems programming, but idk what haskell is good for > > \<sm> it's a language good for many things but people usually get most benefit when you need high quality/high assurance; high expressiveness for implementing complex logic; and/or high maintainability for medium/large codebases over medium/long term\ > \<sm> currently it's often seen in fintech, as the backend for web apps, and for implementing/processing languages\ > \<sm> also, of course, it's very good for teaching and research\ > \<sm> some people learn it early but I think it is most appreciated by experienced software developers\ > \<sm> "an expressive, powerful language for building high quality long lasting software at low cost"\ > \<sm> "as long as the sponsors and spare time volunteers work to keep old GHC versions and deps building on your platform"....\ > \<sm> people often say that knowing a little haskell helps them think/program more clearly in any language\ > \<sm> that's true for me certainly. Haskell is perhaps the best place to learn the functional programming style ### What are some Haskell apps ? The [Cardano] blockchain is one of the most visible large-scale public applications built witih Haskell. %% See it operating here: https://pooltool.io/networkhealth %% Some others are the [Daedalus] wallet for Cardano, and the [SimpleX Chat] secure chat system. The best-known command line apps written in Haskell are [pandoc](https://pandoc.org) (document converter) and [shellcheck](https://www.shellcheck.net) (shell script checker). Here are lists of the Haskell-based projects on github, ranked by stars: [1](https://github.com/EvanLi/Github-Ranking/blob/master/Top100/Haskell.md), [2](https://github.com/search?o=desc&q=language%3AHaskell+stars%3A%3E%3D1000&ref=searchresults&s=stars&type=repositories). Some highlights: **General apps:** | stars | projects | |-------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 40k | [Pandoc] (document converter) | | 10k | [SimpleX Chat] (secure chat system) | | 5k | [kmonad] (keyboard manager), | < | [aura] (package manager), [cardano] (blockchain), [gitit] (wiki), [git-annex] (large file synchroniser), [hakyll] (site generator), [hledger] (accounting app), [ImplicitCAD] (CAD tool), [Wire] (chat server), [patat] (presentation tool), [SimulaVR] (AR/VR interface), [xdg-ninja] ($HOME cleaner), [xmonad] (window manager) [aura]: https://fosskers.github.io/aura/ [Cardano]: (https://iohk.io/en/products) [Daedalus]: https://daedaluswallet.io [git-annex]: https://git-annex.branchable.com [gitit]: https://github.com/jgm/gitit [hakyll]: https://jaspervdj.be/hakyll [hledger]: https://hledger.org [ImplicitCAD]: https://implicitcad.org [kmonad]: https://github.com/kmonad/kmonad [Pandoc]: https://pandoc.org [patat]: https://github.com/jaspervdj/patat [SimpleX Chat]: https://simplex.chat [SimulaVR]: https://simulavr.com [Wire]: https://github.com/wireapp/wire-server [xdg-ninja]: https://github.com/b3nj5m1n/xdg-ninja [xmonad]: https://xmonad.org **Programming tools, not specifically about Haskell:** | stars | projects |-------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 40k | [ShellCheck] (shell script checker) | 30k | [postgrest] (REST API server) | 10k | [duckling] (parsing library), [elm], [PureScript] (programming languages), [hadolint] (dockerfile checker), [Haxl] (remote client library), [IHP] (web framework), [semantic] (code analyser) | 5k | [Unison], [Carp] (programming languages) | < | [Agda], [Copilot], [Futhark], [Kind], [Idris], [Koka] (programming languages), [Bluespec], [Clash] (hardware description languages), [code.world] (introductory IDE), [Corrode] (c/rust translator), [Daedalus] (cardano wallet), [dapp.tools], [echidna], [plutus] (smart contract tools), [Diagrams] (vector graphics language), [miso], [wasp], [Yesod] (web frameworks), [Shake] (build tool), [Tidal Cycles] (music live coding) <!-- tools, libs, frameworks.. --> [Bluespec]: https://github.com/B-Lang-org/bsc [code.world]: https://code.world [dapp.tools]: https://dapp.tools [Diagrams]: https://github.com/diagrams/diagrams [duckling]: https://github.com/facebook/duckling [echidna]: https://github.com/crytic/echidna [hadolint]: https://github.com/hadolint/hadolint [Haxl]: https://github.com/facebook/Haxl [IHP]: https://ihp.digitallyinduced.com [miso]: https://haskell-miso.org [plutus]: https://github.com/IntersectMBO/plutus [postgrest]: https://postgrest.org [semantic]: https://github.com/github/semantic [Shake]: https://shakebuild.com [ShellCheck]: https://shellcheck.net [Tidal Cycles]: https://tidalcycles.org [wasp]: https://wasp.sh [Yesod]: https://www.yesodweb.com <!-- programming and/or proof languages --> [Agda]: https://wiki.portal.chalmers.se/agda/pmwiki.php [Carp]: https://github.com/carp-lang/Carp [Clash]: https://clash-lang.org [Copilot]: https://copilot-language.github.io [Corrode]: https://github.com/jameysharp/corrode [elm]: https://elm-lang.org [Futhark]: https://futhark-lang.org [Idris]: https://www.idris-lang.org [Kind]: https://github.com/HigherOrderCO/Kind [Koka]: https://koka-lang.github.io/koka/doc/index.html [PureScript]: https://purescript.org [Unison]: https://www.unison-lang.org Related: - [What are the best real world applications developed with Haskell?](https://www.reddit.com/r/haskell/comments/2wicxt/what_are_the_best_real_world_applications/) (reddit, 2015) - [Top non-programming-related haskell apps ?](https://www.reddit.com/r/haskell/comments/eddwbu/top_nonprogrammingrelated_haskell_apps/) (reddit, 2019) ### What else is Haskell used for ? Some other notable or common uses of Haskell: - scanning posts for spam at Facebook - analysing code at Github - building programming languages and tools - fintech - cryptocurrency - web apps - command line tools - research - teaching and learning See also: - http://haskellcosm.com - https://wiki.haskell.org/Haskell_in_industry - [11 Companies That Use Haskell in Production](https://serokell.io/blog/top-software-written-in-haskell) - [Open-Source Haskell: 29 Awesome Projects, Tools, and Libraries](https://serokell.io/blog/best-haskell-open-source-projects) - [What is Haskell used for in the real world?](https://stackoverflow.com/questions/1604790/what-is-haskell-used-for-in-the-real-world) (stack overflow, 2020) - https://www.quora.com/What-are-some-real-world-examples-of-large-apps-that-have-been-written-entirely-in-Haskell-or-other-pure-functional-language - https://www.quora.com/What-are-some-real-world-applications-of-Haskell ### How to access the package's version number from code ? Enable the CPP language extension (eg by adding `{-# LANGUAGE CPP #-}` at the top of the source file) and use the `CURRENT_PACKAGE_VERSION` string definition, provided by Cabal. <https://cabal.readthedocs.io/en/stable/cabal-package-description-file.html#conditional-compilation> ### Why should you not use Cabal's Paths_pkgname to access data files ? [Cabal User Guide > Package Description > Accessing data files from package code](https://cabal.readthedocs.io/en/stable/cabal-package-description-file.html#accessing-data-files-from-package-code) describes a way to package data files with your app. You declare them as `data-files:` in the apps's .cabal file, and then you can import helpers from a special `Paths_pkgname` module, which can read the files. However, you should avoid this, because it is fragile: 1. The files will be accessible only if the app was installed in the right way: building/installing it from source with `cabal install` or `stack install` (or installing binary + data files with `nix`) .. 2. They will be installed somewhere like `~/.cabal/store/ghc-9.4.8/...fcfc097/`, which is not a durable place for essential data. Typically, this gets wiped when you uninstall old ghc versions, or when your disk fills up, or when you have an unsolvable cabal/haskell setup problem; or it gets excluded from backups, so won't be there when you restore; or if you copy executables to a new machine, the data won't come along. 3. And once any of these files become inaccessible, the app will no longer run. What to do instead ? One good option at least for smallish files is to embed them in your executable, which makes it much more self-contained, packageable, and robust. The easiest way is using the [file-embed](https://hackage.haskell.org/package/file-embed) library. ([Other embedding libs](https://hackage.haskell.org/packages/search?terms=embed) exist also.) At runtime, instead of reading files from the file system, you use file-embed's API, eg [embedFileRelative](https://hackage.haskell.org/package/file-embed-0.0.16.0/docs/Data-FileEmbed.html#v:embedFileRelative). The type signature is confusing here, but basically it evaluates to a bytestring ([example](https://github.com/simonmichael/hledger/blob/9d4db48510a0e6df4c127ff9751db44ed2066950/hledger/Hledger/Cli/DocFiles.hs#L47)). In cases where you absolutely need real files, eg when a helper app requires that, you can write them out to a temp file at runtime ([example](https://github.com/simonmichael/hledger/blob/9d4db48510a0e6df4c127ff9751db44ed2066950/hledger/Hledger/Cli/DocFiles.hs#L103)). %% Justification for contrarians: ⁦I think it’s reasonable for any cabal user to expect that a binary they built with cabal will keep running, except for the usual reasons (major system upgrade). That’s not true in general if they use this feature. So that should be documented, otherwise many people are misled, they waste time, haskell’s reputation for bad tools continues.⁦ %% ### Should we wrap Haskell code lines at column 80 ? I strongly favour ignoring the 80 character line length convention, and using longer lines when needed (within reason), and viewing with line wrapping usually turned off (ie, with long lines truncated). Because seeing clear code structure, and more of it, is much more valuable than fitting in narrow horizontal space. I usually don’t need to be seeing the end of every line, instead I want to see more of the program. When I do want to see line ends, it’s easy to temporarily maximize a window, scroll, or toggle line wrap. https://discourse.haskell.org/t/supercedes-house-style-for-haskell/11297/16 ### How to use stack and ghcup together efficiently ? If using both stack and ghcup, to avoid wasting space and time it's important to 1. tell stack it can use ghcup's GHCs and need not install GHC itself, and 2. clean up any old stack-installed GHCs (manually, or with a tool like stack-clean-old or ncdu). The easiest way to ensure stack uses ghcup's GHCs is to install stack with ghcup, and say yes when ghcup offers to configure that for you. Otherwise, here's how to configure stack yourself: https://www.haskell.org/ghcup/guide/#stack-integration . Strategy 1 there allows stack to do its usual job of requesting a GHC version compatible with the project you are building (the one requested by the project's stack.yaml, otherwise one compatible with the bounds in the cabal files). Strategy 2 turns that off so it will just try whatever GHC is in PATH. ### Why doesn't ghc (ghci, ...) see a haskell package I've installed ? When you run ghc directly, it uses a "global" package database associated with your user. But when stack or cabal run ghc, it uses the project's package database. Often a quick fix is, while inside the project directory, prepend `cabal exec --` or `stack exec --` to the command. Eg `stack exec -- ghc-pkg list`. cabal and stack also have `repl`/`ghci` commands, which are more fiddly. ### Why does my package build successfully but fail with an error during linking ? It depends. Your first task is to find the relevant error message (not warnings) in the output or build log (it may not be at the end). Often, it will be caused by some required C library that's not installed, like zlib or terminfo. cabal and stack won't install those, and won't warn you ahead of time that they're missing. In this case: install that library (eg by finding its name and using your system's package manager), and try the build again. ### What are some Haskell debug tools ? - https://marketplace.visualstudio.com/items?itemName=phoityne.phoityne-vscode is the VS Code debugger extension for Haskell. Most people will find it too hard to set up and unreliable to use. - https://downloads.haskell.org/ghc/latest/docs/users_guide/ghci.html#the-ghci-debugger in a GHCI window is less pretty but much easier to get working, and more reliable. You'll find it hard to use because of laziness (but, educational). - https://hackage.haskell.org/package/ghcitui adds a basic TUI to the GHCI debugger, which is quite helpful. - https://hackage.haskell.org/package/breakpoint lets you set a breakpoint and then look around with a tiny bit of interactivity. It can be useful. - https://hackage.haskell.org/package/base/docs/Debug-Trace.html is the best place to start. It's an essential tool worth learning. Use :reload in GHCI, or `ghcid`, so you don't have to slowly recompile every time you change a trace call. You can combine it with pretty-show or pretty-simple libs, or fancier libs that build on it. Eg there are some handy helpers in hledger-lib:Hledger.Utils.Debug. - https://hackage.haskell.org/packages/search?terms=debug many more special purpose tools and libs ### How to handle text decoding errors ? jean-paul. hspec insists on blowing up like this on CI: `<stdout>: commitBuffer: invalid argument (cannot encode character '\10003').` Even with --no-unicode. Suppose I can't get UTF-8 in the environment, is it possible to run this test suite? sm I would think not, the only way will be to export LANG=C.UTF-8 or similar (locale -a to check that's installed) sm it's an old problem with GHC and all programs compiled by it. I have resorted to an outer exception handler that tries to detect decode errors by matching error message substrings. sm look at this nonsense: [exitOnError](https://github.com/simonmichael/hledger/blob/master/hledger-lib/Hledger/Utils/IO.hs#L264-L352) sm it's fragile because there's half a dozen different messages, I found another just today geekosaur there's a way to switch ghc's encoding stuff to a lenient mode, but you can't do it "from outside", you have to specifically do it in your program geekosaur https://hackage.haskell.org/package/base-4.21.0.0/docs/System-IO.html#v:mkTextEncoding geekosaur used with https://hackage.haskell.org/package/base-4.21.0.0/docs/System-IO.html#v:hSetEncoding geekosaur note the //IGNORE and //TRANSLIT modifiers sm yup. I think it's pretty hard to achieve user-friendly behaviour currently sm since this kind of non-total text handling behaviour is pervasive sm A combination of an outer handler like mine, both built in and provided as easy paste-in code, plus gradually fixing each of those error generators, would be the way to fix it I think