GHCI vs Prelude command prompt in Haskell - haskell

I am trying to learn Haskell from the beginning and was wondering what exactly is the difference between the two prompts (Haskell and Prelude) that are used in it. It may sound a very naive question and not to mention I tried searching for the answer before posting this question but couldn't find one (proper one). Thank you in advance.

Okay, if I'm understanding this correctly, you're wondering if there's a difference between
Prelude>
and
ghci>
as prompts after you've invoked GHCi from the command line.
If this is the case, then there is no real difference aside from preference. You can change the prompt to whatever you want to by using the command:
:set prompt "aglebargle> "
You can replace arglebargle> with whatever you'd like.
The main advantage I see for the Prelude> prompt is that it will update when you import modules. Prelude is the only module you have without any imports, which is why it's the prompt. E.g., if you, say, did import Control.Monad, you'd get Prelude Control.Monad> as a prompt.

The prompt indicates which module(s) is being worked on and since the Prelude is a standard module for Haskell from GHC it is shown explicitly as the first prompt. However from GHC version 9.x the Prelude is loaded implicitly (unless some directive to the contrary has been given) so the prompt from now on is just "ghci>".
By the way, the Prelude module contains a set of basic types, type classes, and functions to use at the start of any Haskell project without needing to define everything from the beginning.

Related

tryhaskell.org does not seem to support GHCi commands

When I use GHCi commands (i.e. any command starting with ":" for example :set +t) on https://tryhaskell.org/ I get an error:
:1:1: parse error on input ‘:’
According to the documentation of GHCi this should work, but I cannot find much information about it.
I've tried a few other online "repls" as well.
That repl probably doesn't try to provide all of GHCI's functionality. It probably wants to be stateless, so it just evaluates expressions one at a time. No variable definitions, no interacting with GHCI any other way, e.g. through :t. If you install GHCI yourself, you will have a functioning repl. Or, if you want an online repl, https://replit.com/languages/haskell seems to work fine for me.

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.

Why are unpack and show defined differently in Data.Text (and behave differently for non-ASCII characters?)

unpack and show are two ways to convert Text to a String. They, however, behave and are defined differently for non-ASCII characters:
Prelude Data.Text> putStrLn $ unpack $ pack "你好我的朋友"
你好我的朋友
Prelude Data.Text> putStrLn $ show $ pack "你好我的朋友"
"\20320\22909\25105\30340\26379\21451"
With show, I believe, returning a string of codepoints, while unpack displays the actual characters. I have found this to be a nuisance while coding, as I had defined functions that take a Show instance and wanted to pass in Text, and expected it to return the actual non-ASCII characters as a String.
What was the design intent for this behavior? Why were show and unpack defined differently?
The source can be found at http://hackage.haskell.org/packages/archive/text/0.11.1.5/doc/html/src/Data-Text.html.
This is a general thing about Show: it's intended rather to produce a kind of preview of objects that can double as a portable serialisation, readable as Haskell code. Obviously, 你好我的朋友 is not valid Haskell (unless you define it as a variable, which you actually can!), so it would not be acceptable as output of show. It would be quite ok if it produced "你好我的朋友" (in fact, I would prefer that), but this might cause Platform etc. problems when you're not throughoutly using full UTF-8 in all of your work chain, so the safer expansion to ASCII was chosen.
If you want the nice non-escaped plain-string output as the GHCi echo, you can use the new custom-pretty-printer feature. I already wrote something about that here.

Evaluate buffer in ghci or hugs via Emacs

Using sml-mode in Emacs I have been able to send my buffer contents directly to an inferior SML process using C-c C-b. Now I want to do the same thing only with Haskell. Haskell-mode does not seem to support this, so I'm wondering: What is the right way to go about this with Emacs and Haskell?
While learning SML I've been using C-c C-b almost non-stop to easily evaluate my program as I go, instantly seeing the results of assigning values etc. But if I use C-c C-l in haskell-mode on a saved file containing two lines, let foo = "foo" and let bar = "bar" - I get "parse error (possibly incorrect indentation)"
I think you are making a common rookie mistake, confusing what you can write inside the repl of ghci and what you write in a haskell source file.
All sml interpreters are made in such a way that you can write any top level declaration into the repl, or put in other words: anything you can write in an sml file, you can write into the sml interpreter. Thus you are allowed to write val foo = "bar" into a file and use C-c C-b to load the file and you are allowed to just put in val foo = "bar" into the interpreter.
On the other hand, because of how haskell work, you can write let foo = 42 into ghci, however it is not a valid top level declaration and thus this can't be in a haskell source file (by it self). On the other hand you can have id n = n in a haskell source file and use C-c C-l to load the file, however you can't write this directly into ghci (you will get an error: :1:6: parse error on input '='). The reason for this is that the repl in ghci runs in the IO monad, and thus what ever you write into ghci must be done using the do notation. I can only recommend that you read Interactive evaluation at the prompt from the Using GHCi user guide.
C-c C-b in sml-mode is the exact same thing as C-c C-l in haskell-mode, well atleast conceptually. I don't know that much about the internals of haskell-mode, but in sml-mode C-c C-b executes some sml code in the interpreter, normally the use(...) function. In haskell-mode it seems to just excute the :load "..." ghci command
You can't do that with ghci (or hugs) for the simple reason that you can't write top-level definitions in ghci (or hugs). So even if you manually pasted your file's contents into ghci, all you'd get would be a syntax error.
So loading a file using C-c C-l is the best you can do.

GHCi usage question

I am studying Haskell and use Emacs+Haskell mode as my editor.
After playing some simple expressions in GHCi, I am wondering whether these IDE/editor functionality that exist in Visual Stuido for F#:
Can I send the content in the clipboard into the interpreter? Currently I can only :load the file into the interpreter. This is inconvienent when I gradually write functions in a script file. Like 'Alt+Enter' in visual stuido.
After compiling, I hope to see the signature of the function, e.g.
let double x = x + x
so that I can better understand the type inference mechanism in Haskell.
On Windows, there's WinGHCi, a gui including (poor, but often sufficient) support for copy and paste. Dunno about the command line version.
Use :type double (or the shortcut :t double) to get the type signature of double. There's also :info which applies to values (including functions) as well as types and typeclasses (e.g. :info Bool lists the definition of Bool and all typeclasses it is an instance of) and says where it was defined.
Regarding question 2, to see the inferred type of an expression every time you type one in, you can give inside ghci :set +t . I think you could also put that in a .ghci file, inside your home directory, as described in http://www.haskell.org/ghc/docs/6.12.2/html/users_guide/ghci-dot-files.html .
As far as I know, there is no support for sending the clipoards to the interpreter "out of the box", but it should not take more than couple of lines of elisp. I'd look in the support modes for other languages and copied it from there if I were you.
Regarding the types, you could type C-c C-t or C-c C-i on any symbol in your code, which would trigger ":t <symbol>" and ":i <symbol>" commands in the ghci process
TAIM claims to send selected expressions in vim to ghci(haven't tried it)
I'm not sure about function signatures inside the editor but in ghci its ":t func"
Actually looking at their youtube video it looks like TAIM may be able to select ":t func" in vim and send it to interpreter.

Resources