21

Defining a function signature in Haskell's interpreter GHCi doesn't work. Copying an example from this page:

Prelude> square :: Int -> Int

<interactive>:60:1: error:
    • No instance for (Show (Int -> Int)) arising from a use of ‘print’
        (maybe you haven't applied a function to enough arguments?)
    • In a stmt of an interactive GHCi command: print it
Prelude> square x = x * x

How can I declare a function signature and then give function definition in Haskell interactively? also: why can't I simply evaluate the function and see its type (e.g. Prelude> square) once it has been defined?

jll
  • 805
  • 2
  • 8
  • 16
  • Possible duplicate of [How to define a function in ghci across multiple lines?](https://stackoverflow.com/questions/2846050/how-to-define-a-function-in-ghci-across-multiple-lines) – Chris Martin Jul 29 '17 at 00:48

3 Answers3

34

You can define a function signature in the ghc interactive shell. The problem however is that you need to define functions in a single command.

You can use a semicolon (;) to split between two parts:

Prelude> square :: Int -> Int; square x = x * x

Note that the same holds for a function with multiple clauses. If you write:

Prelude> is_empty [] = True
Prelude> is_empty (_:_) = False

You have actually overwritten the previous is_empty function with the second statement. If we then query with an empty list, we get:

Prelude> is_empty []
*** Exception: <interactive>:4:1-22: Non-exhaustive patterns in function is_empty

So ghci took the last definition as a single clause function definition.

Again you have to write it like:

Prelude> is_empty[] = True; is_empty (_:_) = False
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • thank you. quick final followup: if i define it on one line, why can't i evaluate it after? ``Prelude> square`` returns ``Parse error: module header, import declaration or top-level declaration expected.`` – jll Jul 27 '17 at 23:22
  • full trace: ``Prelude> square :: Int -> Int; square x = x * x Prelude> square :70:1: error: • No instance for (Show (Int -> Int)) arising from a use of ‘print’ (maybe you haven't applied a function to enough arguments?) • In a stmt of an interactive GHCi command: print it Prelude> square;; :71:1: error: Parse error: module header, import declaration or top-level declaration expected.`` – jll Jul 27 '17 at 23:24
  • @jll: but why do you write two additional semi-colons? You can calculate a square like with for instance `square 3`. The reason why `square` errors is because it is a function, and Haskell - by default - can not show functions. – Willem Van Onsem Jul 27 '17 at 23:27
  • it's confusing to me because I can evaluate instances of other types like ``1`` so if functions are first class why can't i evaluate a function and haskell print its type? i expected something like ``square :: Int -> Int`` as output – jll Jul 27 '17 at 23:33
  • 1
    @jll: you can inspect the type of an expression with `:t`, so `:t square`. – Willem Van Onsem Jul 28 '17 at 00:01
18

Multi-line input needs to be wrapped in the :{ and :} commands.

λ> :{
 > square :: Int -> Int
 > square x = x * x
 > :}
square :: Int -> Int
Chris Martin
  • 30,334
  • 10
  • 78
  • 137
13

Here are three ways:

>>> square :: Int -> Int; square = (^2)
>>> let square :: Int -> Int
...     square = (^2)
...
>>> :{
... square :: Int -> Int
... square = (^2)
... :}

The second one requires you to :set +m; I include this in my ~/.ghci so that it is always on.

Daniel Wagner
  • 145,880
  • 9
  • 220
  • 380
  • important caveat: there must be no trailing spaces after `let square :: Int -> Int` for the second option to work. – Will Ness Jan 25 '22 at 17:32