Just call ghci
from the command line to open a REPL.
The prompt name is set to whichever module was last imported into the scope. Normally this will be Prelude
, Haskell's standard library.
You can also reset the modules in scope with the command :m
(or :module
) with no arguments.
Commands are prepended with :
, e.g. :q
, :reload
.
You can use external shell commands with :!
, e.g. :!cls
(clears screen on Windows)
Load packages into the REPL with :l
, e.g. :l functions.hs
.
:{
...
:}
(Don't forget you can also 'insert' line breaks with semicolons)
Everything in Haskell can be thought of as an expression or a declaration. Expressions can be literals or operations. Declarations name expressions. Haskell programs are nothing but large expressions comprising smaller ones.
...is significant. Make sure parts of expressions are indented underneath the start of each, e.g.
foo x =
let y = x * 2
z = x ^ 2
in 2 * y * z
Functions are simply expressions that have arguments applied. Haskell functions are essentially partially applied: every argument passed creates a new curried function, e.g.
partialApplication x y z = x + y + z
s1 = partialApplication 1
s2 = s1 2
s3 = s2 3
s3 -- emits '6'
Haskell functions are generally called in the prefix style -
div 12 4
truncate "Hello, world" 5
Whereas operators are functions called in the infix style -
4 + 6
"hello " ++ "world"
But non-operator functions can be called in an infix style using ` characters -
12 `div` 4
"Hello, world" `truncate` 5
And you can use the infix operators in a prefix fashion by wrapping them in parens -
(+) 10 6
(*) 3 4
(+3) 7
You can query the signature and prefix / infix nature of a function on the REPL using :info
(e.g. :info div
or :info \
)
For instance, :info *
-
class Num a where
...
(*) :: a -> a -> a
...
-- Defined in `GHC.Num'
infixl 7 *
Means that * is an infix operator, with left associativity, applied with level 7 precedence (0-9, higher comes earlier).
When operator precedence is in doubt, you can of course always wrap values in parentheses.
(+1) (2 * 3)
You can also use the $
operator
(+1) $ 2 * 3
How does this work? Well, $
is defined as
f $ x = f x
Which means anything to the right of $
gets treated as a single parameter to the left-hand function (essentially enforcing right-hand associativity)
A lot of Haskell literature uses the term 'reduction' to talk about evaluation - essentially like the mathematical reduction of functions. Once expressions are fully reduced, they are in a 'canonical' or 'normal' form:
foo = triple 3 -- not reduced
foo = 3 * 3 -- reduce x1
foo = 9 -- reduced to normal form
Haskell, being a lazy language, doesn't reduce all expressions to normal form by default. Instead it tries to reduce to weak head normal form (such that only the outer constructor of the expression is evaluated)
::
== 'has the type signature'
All Haskell operators are just functions called in the infix style.
++
concatenate