Cannot enter multiline statements in GHCi [duplicate] - haskell

This question already has answers here:
Multi-line commands in GHCi
(5 answers)
Closed 9 years ago.
let x=1
y=2
z=3
does not work in GHCi, forcing me to use let {x=1;y=2;y=3} instead. How can I fix this problem?

The documentation says:
GHCi also has a multiline mode, enabled by :set +m, in which GHCi detects automatically when the current statement is unfinished and allows further lines to be added. A multi-line input is terminated with an empty line.
The multiline mode makes GHCi behave much like e.g. the Python interpreter:
Prelude> :set +m
Prelude> let x = 1
Prelude| y = 2
Prelude| z = 3
Prelude|
Prelude> (x, y, z)
(1,2,3)
This hidden gem is wonderful for playing with readable code!
If you want this to be the default behaviour, you can create a .ghci file in your home directory with a line saying :set +m. (Now that this came up, I actually did so.)

Related

Should I avoid using interactive mode?

Haskell newbie here. I use ghci to implement a baby quicksort algorithm [1] as follows:
Prelude> quicksort (firstx:xs) = quicksort[x|x<-xs, x<firstx] ++ [firstx] ++ quicksort[x|x<-xs, not(x<firstx)]
Prelude> quicksort [] = []
The command quicksort [1,2,3] then gives an error:
*** Exception: :8:1-17: Non-exhaustive patterns in function quicksort
However, typing the exact same thing in an quicksort.hs file and running $ ghci quicksort.hs do not yield such an error.
Question
What makes the difference? Is it a rule of thumb that one should avoid using interactive mode?
Reference
[1] Rex Page. Two Dozen Short Lessons in Haskell
It's generally easier to define a multi-line function in a file and then load :l <module> or reload :r, but I do sometimes declare a multi-line function directly in GHCi starting with :{ and :}:
:{
quicksort (firstx:xs) = quicksort[x|x<-xs, x<firstx] ++ [firstx] ++ quicksort[x|x<-xs, not(x<firstx)]
quicksort [] = []
:}
:h is useful if you forget any commands while in GHCi.
Edit: forget to address the second part of your question.
Is it a rule of thumb that one should avoid using interactive mode?
Interactive mode is a great tool and I miss it in other ecosystems like ReasonML that do not have one. There is no reason to avoid it. Just remember to copy your code over if you come up with some that you want to keep.

Compiled vs Interpreted: To Let or Not To Let

Why does the Haskell interpreter (GHCI 7.10.3) need function definitions to be in a let expression, but the Haskell compiler (GHC 7.10.3) throws a parser error if a function definition is within a let expression?
I'm working through "Learn You a Haskell for Great Good!" Baby's first function is doubleMe:
doubleMe x = x + x
Why does the interpreter accept this definition if it is within a let expression and otherwise throw a parse error on input '='? Meanwhile, if I'm compiling the same function from a file, why does GHC throw a parse error if the function definition is within a let expression and compiles the definition if it is not within a let expression? Coming from a Lisp background, I'm surprised that interactive Haskell and file loading and compilation Haskell treats these definitions differently.
The reasoning behind this is that GHCi (in 7.10.3) expects at the prompt only
commands (type in :h to list the commands available)
declarations (things like data, type, newtype, class, instance, deriving, and foreign but not a regular definition)
imports
expressions (things like 1+1 or let x = 3 in x*x)
I/O Actions / do statments (things like print "hi" or x <- getLine OR let doubleMe x = x + x)
If this seems surprising to you, remember that the evaluation of Lisp and Haskell is very different - Lisp just gets interpretted, while Haskell is being compiled.
As you can tell, top-level definitions are not part of this list. Thankfully this got fixed in GHCi 8.0.1, which now supports raw top-level function declarations. The following works (in 8.0.1):
ghci> doubleMe x = x + x
ghci> doubleMe 1
2
The GHCi interpreter command line treats its input as if it were in a do clause. So you can type this:
:module + System.Random
v <- getStdRandom $ randomR (1,10)
Apart from the :module directive this is exactly how it would be in a do clause.
Likewise you can write
let f x = 2 * x
because that is how it would be in a do clause.
Modern Lisp implementations compile to native code, often by default even when code is entered at the prompt. Lisp's prompt isn't just a place to enter commands, it's a place to interact with the language because the entire language is made available by the Read-Evaluate-Print Loop. This means that Lisp reads the text into symbolic expressions, which it then evaluates, printing any print output and any returned values. For example,
? (defun a-fun () nil)
A-FUN
? (compiled-function-p #'a-fun)
T
Compiled-Function-P
Clozure Common Lisp
With Lisp, code you can enter into the Lisp image by compiling and loading a file you can also enter into the Lisp image by typing it out at the REPL. So it turns out I was surprised because I was expecting the GHCi prompt to be a REPL, but as #Alec describes it's not because it doesn't read text into Haskell expressions that it would then evaluate, as Lisp does. As #dfeuer says, the issue isn't about compilation versus interpretation. The issue is that GHCi's prompt offers limited interaction with a Haskell compiler, rather than interaction with Haskell itself as Lisp's REPL does.

Reading stdin in ghci on Linux is broken

Comming from Windows, I have recently installed linux distribution named Peppermint and Haskell-Platform via bash (ghc 7.10) but there must be something wrong with ghci stdin in ghci because :
interact $ take 0
throws an error but
interact $ take 1
does not.
Furthermore, if I use backspace, arrows or any other control button when writing into stdin, it enters the char symbol. For example backspace enters ^? into ghci instead of deleting the last char typed...
...#... ~ $ ghci
GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help
Prelude> interact $ take 0
Prelude>
<stdin>: hGetChar: illegal operation (handle is closed)
...#... ~ $ ghci
GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help
Prelude> readLn :: IO String
euoe^?^?^[[1;5C^[[D^[[B -- here I tried to delete 'euoe'
Regarding the control code literals, this is because you've managed to escape all of the line editors (readline, Haskeline) that would usually interpret your key presses.
I don't know the particulars, but invoking GHCi is something like starting a subshell with bash --noediting. This allows GHCi to receive raw key presses without interference from the readline library. This is done because Haskeline—which GHCi uses in place of readline—can be configured with things like tab completion for available functions more easily (you knew GHCi provided tab completion, right?).
Calling getLine from GHCi then effectively drops through a trap door and dodges Haskeline completely by going straight to stdin. There is, after all, only one stdin. You're now typing directly into an unbuffered terminal.
Getting back to your first concern, there being only one stdin is also why GHCi immediately keels over after printing the Prelude> prompt. interact (which uses hGetContents behind the scenes) claims that it will address all of the input that will ever come through the handle (stdin) as one big lazy String. Effectively there can be no remaining input on the handle that interact hasn't already claimed to deal with, so the handle is immediately put into a “semi-closed” state. It's not closed (there could still be more input that will be read as part of that lazy String interact gets!) but it is closed to any newcomers, otherwise input would get duplicated (interact and new readers of the handle such as getLine would get the same line!).
Back to GHCi, after having used interact, stdout is still fine so the prompt gets printed as usual, then GHCi leans on Haskeline to return a line for processing. Haskeline (as a line editor) calls a blocking getChar (iirc) to either add a character to the line or perform some line editing command and dies because it's addressing a semi-closed handle. Thus a weaker creature does fall and the great wheel of life rolls on.

parse error on input '->' when using case [duplicate]

This question already has an answer here:
Why shouldn't I mix tabs and spaces?
(1 answer)
Closed 5 years ago.
I'm learning haskell by going through learn you a haskell for great good and one of the functions in the tutorials doesn't seem to compile. I can't figure out why, I thought it might be the indenting but it doesn't seem to make a difference. Most of the SE questions seems to be referring to the ghci and trying to set variables.
describeList :: [a] -> String
describeList xs = "The list is " ++ case xs of [] -> "empty."
[x] -> "a singleton list."
xs -> "a longer list."
The error I get is:
describeList.hs:4:95: parse error on input '->'
Failed, modules loaded: none.
Turns out the problem was with my tab settings on VIM. Turns out Haskell is quite particular with the indentations. I changed my vimrc file to these settings.
" Tab specific option
set tabstop=8 "A tab is 8 spaces
set expandtab "Always uses spaces instead of tabs
set softtabstop=4 "Insert 4 spaces when tab is pressed
set shiftwidth=4 "An indent is 4 spaces
set shiftround "Round indent to nearest shiftwidth multiple
Source: http://www.haskell.org/haskellwiki/Vim

Find inferred type for local function

Is there a way in ghci (or ghc) to find what the inferred type of a local function is?
E.g. if I have a function
f l = map f' l
where f' = (+1)
is there a :t-like way in ghci to see what the inferred type for f' is?
Indeed there is, which I learned about thanks to hammar's awesome answere here. Here's the short version:
Prelude> :l /tmp/foo.hs
[1 of 1] Compiling Main ( /tmp/foo.hs, interpreted )
Ok, modules loaded: Main.
*Main> :break f
Breakpoint 0 activated at /tmp/foo.hs:(1,1)-(2,18)
*Main> f [1..10]
Stopped at /tmp/foo.hs:(1,1)-(2,18)
_result :: [b] = _
[/tmp/foo.hs:(1,1)-(2,18)] *Main> :step
Stopped at /tmp/foo.hs:1:7-14
_result :: [b] = _
f' :: b -> b = _
l :: [b] = _
[/tmp/foo.hs:1:7-14] *Main> :t f'
f' :: b -> b
I don't know of any way of doing it from GHCi.
However, if you're using an editor like Emacs or Vim, you can try ghc-mod. This is an external tool that plugs into an editor and gives you some IDE-like functionality for Haskell programs, including the ability to get the type of an arbitrary expression, including a local definition.
In Emacs, you would use C-c C-t to find the type of an expression.
If you're not using Emacs or Vim, you could probably wrap ghc-mod as a GHCi extension or something, but I think that would be somewhat awkward. I can't imagine a good way to do it without having an editor-like UI. However, ghc-mod itself is just a standalone command-line tool, so it's easy to work with. If you can think of a good user interface for it that's independent of an existing text editor, go for it!
Of course, if you're not using Emacs or Vim, you probably should :P.
Try hdevtools, it's quite fast and easy to use, though there's only integration for Vim.

Resources