Reputation: 4523
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
Upvotes: 168
Views: 47444
Reputation: 13664
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
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.
Upvotes: 7
Reputation: 394965
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
Upvotes: 5
Reputation: 1751
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
.
Upvotes: 152
Reputation: 4985
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.
Upvotes: 222
Reputation: 8050
Use let
:
Prelude> :{
Prelude| let addTwo :: Int -> Int -> Int
Prelude| addTwo x y = x + y
Prelude| :}
Prelude> addTwo 2 3
5
Upvotes: 15