Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multi-line commands in GHCi

People also ask

How do I make multiple lines in command prompt?

The Windows command prompt (cmd.exe) allows the ^ (Shift + 6) character to be used to indicate line continuation. It can be used both from the normal command prompt (which will actually prompt the user for more input if used) and within a batch file.

What does GHCi mean in Haskell?

Introduction. GHCi is GHC's interactive environment, in which Haskell expressions can be interactively evaluated and programs can be interpreted.


Most of the time, you can rely on type inference to work out a signature for you. In your example, the following is sufficient:

Prelude> let addTwo x y = x + y

If you really want a definition with a type signature, or your definition spans over multiple lines, you can do this in ghci:

Prelude> :{
Prelude| let addTwo :: Int -> Int -> Int
Prelude|     addTwo x y = x + y 
Prelude| :}
Prelude> addTwo 4 7
11

Note that you can also squeeze this onto one line:

Prelude> let addTwo :: Int -> Int -> Int ; addTwo x y = x + y

You can find out more about interacting with ghci on the Interactive evaluation at the prompt section of the documentation.


Solve this problem by firing up GHCI and typing :set +m:

Prelude> :set +m
Prelude> let addTwo :: Int -> Int -> Int
Prelude|     addTwo x y = x + y
Prelude| 
Prelude> addTwo 1 3
4

Boom.


What's going on here (and I'm talking mostly to you, person googling for help while working your way through Learn You A Haskell) is that GHCI is an interactive environment where you're changing bindings of function names on the fly. You have to wrap your function definitions in a let block, so that Haskell knows that you're about to define something. The :set +m stuff is shorthand for the multiline :{ code :} construct.

Whitespace is also significant in blocks, so you have to indent your function definition after your type definition by four spaces to account for the four spaces in let.


Use let:

Prelude> :{
Prelude| let addTwo :: Int -> Int -> Int
Prelude|     addTwo x y = x + y
Prelude| :}
Prelude> addTwo 2 3
5

As of GHCI version 8.0.1, let is no longer required to define functions on the REPL.

So this should work fine for you:

λ: addTwo x y = x + y
λ: addTwo 1 2
3
λ: :t addTwo
addTwo :: Num a => a -> a -> a

Haskell's type-inference provides generalized typing that works for floats as well:

λ: addTwo 2.0 1.0
3.0

If you must provide your own typing, it seems you'll need to use let combined with multiline input (use :set +m to enable multiline input in GHCI):

λ: let addTwo :: Int -> Int -> Int
 |     addTwo x y = x + y
 | 
λ: addTwo 1 2
3

But you'll get errors if you try to pass anything but an Int because of your non-polymorphic typing:

λ: addTwo 2.0 1.0

<interactive>:34:8: error:
    • No instance for (Fractional Int) arising from the literal ‘2.0’
    • In the first argument of ‘addTwo’, namely ‘2.0’
      In the expression: addTwo 2.0 1.0
      In an equation for ‘it’: it = addTwo 2.0 1.0

To expand on Aaron Hall's answer, in version GHCi 8.4.4 at least, you don't need to use let with type declarations if you use the :{ :} style. This means you don't have to worry about adding the 4-space indentation on every subsequent line to account for let, making longer functions much easier to type, or in many cases, copy-paste (since the original source likely won't have the correct indentation):

λ: :{
 | addTwo :: Int -> Int -> Int
 | addTwo x y = x + y
 | :}
λ: addTwo 1 2
3

Update

As an alternative you can turn on multi-line input mode with :set +m, then type let on its own, hit Enter, then paste definitions with no indentation required.

However this doesn't seem to work with some code blocks, such as:

class Box a where
  mkBox :: a -> Boxes.Box

But the :{, :} technique does.