1

^-- No, it doesn't entirely. My question covers ADDING patterns and type signatures interactively...which is apparently impossible.

The most basic things you might try do from early tutorials won't work in GHCi:

foo [] = []
foo (x:xs) = x : foo xs

That works if you put it into foo.hs and at the GHCi prompt type :load foo.hs. You can then invoke foo on a list and get the list back.

Early Google searches tell you that in GHCi you need a let statement. But in this case (a function defined with multiple patterns) it won't work:

Prelude> let foo [] = []
Prelude> let foo (x:xs) = x : foo xs
Prelude> foo [1, 2, 3]
[1,2,3*** Exception: <interactive>:3:5-27: Non-exhaustive patterns 
    in function foo

The second "let" overwrote the first "let". Leaving out the let isn't an option. And it doesn't like it if you type in expressions like foo :: [a] -> [a] either.

The tutorials seem to sidestep this and send you quickly into putting your code into files. What if you don't want to make a file, and want to work interactively? What are the options?

  • 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) – Ionuț G. Stan Jul 27 '14 at 03:46
  • possible duplicate of [Multi-line commands in GHCi](http://stackoverflow.com/questions/8443035/multi-line-commands-in-ghci) – Sibi Jul 27 '14 at 03:47
  • @IonuțG.Stan I've read that. That isn't the same question. And the knowledge that a "let" statement would group with everything after it is a very specific oddity. So basically if I have a file full of definitions from a tutorial, I say "let" once and it doesn't matter what the ensuing contents are? – HostileFork says dont trust SE Jul 27 '14 at 03:50

2 Answers2

3

No. You cannot add new patterns or a type signature to a function in GHCi after you have run a statement defining it in the evaluator.

For that matter, you shouldn't see it as "adding" on a line-by-line basis in source code, either. It's merely a notation convenience. So when you look at a "multi-line" definition like:

foo :: [a] -> [a]
foo [] = []
foo (x:xs) = x : foo xs

Those foo definitions must all be tied together as a group. You can't split them up...so for instance, this will cause an error:

foo :: [a] -> [a]
foo [] = []

bar = 3

foo (x:xs) = x : foo xs

(Note: The type signature may be separated, however. For the details of how far it can be separated, see How is 'block' granularity in Haskell defined? )

To put things together as a group, you can use multi-line input in GHCi. Or you could do it all on one line with semicolons:

let foo :: [a] -> [a] ; foo [] = [] ; foo (x:xs) = x : xs

But you can't type in an input, test it, then patch individual patterns in and out, and test it again. The whole function is redefined with each let.

Community
  • 1
  • 1
2

Use multiline input:

Prelude> :set +m
Prelude> let
Prelude| foo [] = []
Prelude| foo (x:xs) = x : foo xs
Prelude| 
Prelude> foo [1,2,3]
[1,2,3]
vivian
  • 1,434
  • 1
  • 10
  • 13
  • Is there no way to specify N patterns, try it, get a problem, and adjust it without a multi-line input specifying all the patterns again? – HostileFork says dont trust SE Jul 27 '14 at 03:52
  • @HostileFork, not at the moment. There is a suggestion that an entire multiline input can be restored from the input history but it is not yet implemented. – vivian Jul 27 '14 at 03:54
  • Hmm. It seems one cannot split up the patterns for foo with an interspersed other definition *(such as `foo [] = []` followed by `bar = 3` then `foo (x:xs) = x : foo xs`)* So even if you're entering them in source, they are effectively defined all in an instant... so there is no "line-by-line" even there. Correct? – HostileFork says dont trust SE Jul 27 '14 at 04:00
  • 1
    @HostileFork All the equations for one function/variable must be consecutive, same as in a file. And everything from the `let` to the empty line is parsed in one go, as a `let` block. (GHCi is being lenient by not requiring extra indentation for the block items in this case.) – Ørjan Johansen Jul 27 '14 at 04:39
  • @HostileFork BTW in GHCi (and lambdabot) I tend to use explicit `;` and the very occasional `{}` braces (not as often needed as you'd think) instead of multiline. Mostly old habit, but this does have the advantage that I *can* usually re-edit the whole line in one go. – Ørjan Johansen Jul 27 '14 at 04:45
  • @ØrjanJohansen Thanks...see [my attempt](http://stackoverflow.com/a/24978075/211160) at answering my own question. Any nuance you care to add? It seems the type signature may be separated from the function definitions, but you can't independently do a let of a type signature that I can tell... – HostileFork says dont trust SE Jul 27 '14 at 05:06
  • @HostileFork Indeed, the type signature isn't required to be consecutive with the equations, but it must be in the same block. – Ørjan Johansen Jul 27 '14 at 05:34
  • @ØrjanJohansen Is there a formal definition of a Haskell "block" pertinent to this? I see "do-block" mentioned, but if you are using source files then what is the granularity of a block? – HostileFork says dont trust SE Jul 27 '14 at 05:53
  • @HostileFork Curiously the Haskell Report barely uses the term "block", speaking of [layout](http://www.haskell.org/onlinereport/haskell2010/haskellch2.html#x7-210002.7) instead. There are four standard kinds, `where`, `let`, `do` and (`case`) `of` blocks. The first two are the ones which can have function declarations and the like. A whole source file is technically an optional module declaration followed by a kind of `where` block. – Ørjan Johansen Jul 27 '14 at 06:36
  • @ØrjanJohansen Interesting enough point for a [new question](http://stackoverflow.com/questions/24978563/how-is-block-granularity-in-haskell-defined), I think... – HostileFork says dont trust SE Jul 27 '14 at 06:41