April 24, 2025

Haskell in 2025 - using Ghci

Ghci is an interactive Haskell. Like many languages, you can fire up Haskell (as ghci) and type statements and expressions to it and immediately see the results.

I have never been a fan of this. I prefer to just use my editor and write programs. Also there are a number of differences between how Haskell acts via ghci and what you can write in a Haskell program.

As one example, you can type "let a=10" in ghci any time you like. Try using let in a regular Haskell program and you will get strange errors about indentation unless you use it in specific places. One of those places is in "do" blocks -- and there is a mystical connection between ghci and do notation.

As of the current version (9.6.6) ghci no longer prints "Prelude>" as the prompt, but rather "ghci>". This seems like a good change and fine to me, but you will encounter dozens of tutorials that show ghci giving the "Prelude>" prompt, so don't be alarmed.

Ghci has a host of "helper" commands that are triggered by a leading colon ":" such as ":t" (which shows the type of the argument). I won't duplicate other resources by trying to enumerate them all here.

Ghci introduces a variable "it" that gets set to the value of the most recent expression that has been typed. This can be a lazy shorthand for subsequent statements, sort of like a "recall" button on certain calculators.

Use gHCi as a desk calculator

It is so-so -- and perhaps most useful if you are aware of every Haskell quirk. For example I try this:
ghci> .25 * 25.4
:2:1: error: [GHC-58481] parse error on input ‘.’
ghci> 0.25 * 25.4
6.35
Yes, it wants a leading zero on that 0.25. There is also the issue of negative numbers where "-" is a unary negation operator rather than part of a numeric constant. This may require (-3) to avoid certain parse errors.

GHCI and "do" notation

The way Ghci handles this goes hand in hand with what I have already said about "let". What they say is that "the syntax of what you type to the ghci prompt is exactly the same as what you place into a Haskell do statement.

Ghci and the "monomorphism" restriction

You can read more about this here: I will repeat what I have already said -- I avoid Ghci because it differs in so many ways from GHC. I have not yet fully grokked all this about monomorphism, but it is interesting to read that the issue is considered a "wart" in the Haskell language. And fundamental "wart" aside, it is ever more interesting in light of the current discussion that GHC and GHCi have different defaults for this behavior. This is something I can dig into someday or perhaps trip over.

If you are going down this road, you might read the oft quoted 2007 paper (55 page PDF), "A History of Haskell, Being Lazy with Class".


Feedback? Questions? Drop me a line!

Tom's Computer Info / tom@mmto.org