162

I am having problem in entering multi-line commands in ghci.

The following 2-line code works from a file:

addTwo :: Int -> Int -> Int
addTwo x y = x + y

But when I enter in ghci, I get an error:

<interactive>:1:1: error:
    Variable not in scope: addTwo :: Int -> Int -> Int

I also tried putting the code inside :{ ... :}, but they are also not working for this example, because this is just appending the lines into one line, which should not be the case.

I am using WinGHCi, version 2011.2.0.1

Will Ness
  • 70,110
  • 9
  • 98
  • 181
R71
  • 4,283
  • 7
  • 32
  • 60
  • 2
    possible duplicate of [How to define a function in ghci across multiple lines?](http://stackoverflow.com/questions/2846050/how-to-define-a-function-in-ghci-across-multiple-lines) – devnull May 18 '14 at 01:48

5 Answers5

214

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.

Nicolas Wu
  • 4,805
  • 2
  • 25
  • 32
  • 1
    Thanks very much for both the solutions. But I have another related question: why are the four leading blanks required in the second line (before addTwo)? And this has to be exact, if there are less or more blanks, then there is an error. – R71 Dec 09 '11 at 12:26
  • 10
    @Rog `let` begins a block; entries in a block are grouped by indentation; and the first non-whitespace character in a block sets the indentation by which they're grouped. Since the first non-whitespace character in the `let` block above is the `a` of `addTwo`, all lines in the block must be indented exactly as deep as that `a`. – Daniel Wagner Dec 09 '11 at 12:40
  • Thanks. I also noticed that in other let/where blocks. This is a big difference from other languages where whitespace is ignored, so I had some difficulty in grasping that. – R71 Dec 10 '11 at 11:53
147

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.

adrian
  • 1,701
  • 1
  • 11
  • 5
  • 5
    So simple, but not obvious. I wanted to scream at the book I was using for not telling me that on page 1! – Tim Aug 11 '16 at 15:54
  • 6
    From a Linux shell, `echo ':set +m' >> ~/.ghci` to make this setting persistent. – daparic Nov 01 '18 at 21:32
  • 1
    you can have `let` by itself on the first line then all the rest do not need to be indented at all. where the whitespace truly counts is there must not be trailing spaces on your lines. trailing whitespace counts as an extra Enter and breaks the multi-line block. – Will Ness May 12 '20 at 06:16
15

Use let:

Prelude> :{
Prelude| let addTwo :: Int -> Int -> Int
Prelude|     addTwo x y = x + y
Prelude| :}
Prelude> addTwo 2 3
5
Stefan Holdermans
  • 7,990
  • 1
  • 26
  • 31
6

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.

Will Ness
  • 70,110
  • 9
  • 98
  • 181
davidA
  • 12,528
  • 9
  • 64
  • 96
  • 1
    actually, even before, you could type `:{`, then on the next line `let` by itself, then paste your definitions with no added indentation whatsoever, then close with `:}`. :) and with multi-line input mode set (`:set +m`) you didn't even need the braces commands as long as there were no trailing spaces on the code lines. – Will Ness May 12 '20 at 06:09
  • Ah, so with `:set +m` you can just use `let` on its own line? So you can - that's cool. Thank you. – davidA May 14 '20 at 01:50
  • Hmm, I've found some cases where simply typing `let` then newline does not work. See my edit. – davidA May 14 '20 at 05:32
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
Russia Must Remove Putin
  • 374,368
  • 89
  • 403
  • 331