GHCi usage question - haskell

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.

Related

Preprocessor for haskell source: is cpp the only option?

I can see from plenty of Q&As that cpp is the usual preprocessor for Haskell source; but that it isn't a good fit for the job. What other options are there?
Specifically:
Haskell syntax is newline-sensitive and space/indent-sensitive -- unlike C, so cpp just tramples on whitespace;
' in Haskell might surround a character literal, but also might be part of an identifier (in which case it won't be paired) -- but cpp complains if not a char literal;
\ gets a trailing space inserted -- which is not a terrible inconvenience, but I'd prefer not.
I'm trying to produce a macro to generate an instance from parameters for a newtype type and corresponding data constructor. It needs to generate both the instance head and constraints and a method binding. By just slotting the constructors into an instance skeleton.
(Probably Template Haskell could do this; but it seems rather a large hammer.)
cpphs seems to be just about enough for my (limited) purposes. I'm adding this answer for the record; an answer suggesting cpphs (and some sensible advice to prefer Template Haskell) was here and then gone.
But there's some gotchas that meant at first sight I'd overlooked how it helped.
Without setting any options, it behaves too much like cpp to be helpful. At least:
It doesn't complain about unpaired '. Indeed you can #define dit ' and that will expand happily.
More generally, it doesn't complain about any nonsense input: it grimly carries on and produces some sort of output file without warning you about ill-formed macro calls.
It doesn't insert space after \.
By default, it smashes together multiline macro expansions, so tramples on whitespace just as much.
Its tokenisation seems to get easily confused between Haskell vs C. specifically, using C-style comments /* ... */ seems to upset not only those lines, but a few lines below. (I had a #define I wanted to comment out; should have used Haskell style comments {- ... -} -- but then that appears in the output.)
The calling convention for macros is C style, not Haskell. myMacro(someArg) -- or myMacro (someArg) seems to work; but not myMacro someArg. So to embed a macro call inside a Haskell expression probably needs surrounding the lot in extra parens. Looks like (LISP).
A bare macro call on a line by itself myInstance(MyType, MyConstr) would not be valid Haskell. The dear beastie seems to get easily confused, and fails to recognise that's a macro call.
I'm nervous about # and ## -- because in cpp they're for stringisation and catenation. I did manage to define (##) = (++) and it seemed to work; magicHash# identifiers seemed ok; but I didn't try those inside macro expansion.
Remedies
(The docos don't make this at all obvious.)
To get multi-line output from a multi-line macro def'n, and preserving spaces/indentation (yay!) needs option --layout. So I have my instance definition validly expanded and indented.
If your tokenisation is getting confused, maybe --text will help: this will "treat input as plain text, not Haskell code" -- although it does still tolerate ' and \ better. (I didn't encounter any downsides from using --text -- the Haskell code seemed to get through unscathed, and the macros expanded.)
If you have a C-style comment that you don't want to appear in output, use --strip.
There's an option --hashes, which I imagine might interact badly with magicHash#.
The output file starts with a header line #line .... The compiler won't like that; suppress with --noline.
I would say that Template Haskell is the most perfect tool for this purpose. It is the standard set of combinators for constructing correct Haskell source code. After that there is GHC.Generics, which might allow you to write a single instance that would cover any type which is an instance of Generic.

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.

GHCI vs Prelude command prompt in 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.

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.

Haskell autocompletion in Emacs using haskell-mode

I installed haskel-mode in emacs. Then I write in my .emacs:
(load "~/.emacs.d/haskell-mode/haskell-site-file")
(add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode)
(add-hook 'haskell-mode-hook 'turn-on-haskell-indentation)
(add-hook 'haskell-mode-hook 'haskell-font-lock-symbols t)
(put 'downcase-region 'disabled nil)
What must I add in my conf file that emacs could autocomplete for Haskell? Or Haskell mode there is no such possibility?
When there is no language-specific support, you can use tags. This is a generic completion mechanism.
Generate a TAGS file, which contains a list of identifiers and where they are defined. Emacs comes with the etags program to do this in many languages, but not Haskell; ghc comes with hasktags.
Load the TAGS file with M-x visit-tags-table.
Tags are not context-dependent, so they'll indiscriminately suggest types, values, constructors, etc everywhere. They also won't provide advanced features such as easily showing the type of a value. The most important tags commands are:
M-TAB (complete-symbol) completes an identifier according to the loaded list of tags.
M-. (find-tag) goes to the place where the identifier at point is defined, opening the containing file if necessary.
M-* (pop-tag-mark) goes back where you were before M-..
M-x tags-apropos shows a list of identifiers matching a regexp.
For more information, look under "Tags" in the Emacs manual.
For an even cruder, but fully automatic mechanism, there is the dynamic abbrev feature. C-M-/ (dabbrev-completion) looks in most open buffers for a completion; this is completely language-independent, so it'll even find words in strings, comments, whatever. M-/ (dabbrev-expand) is similar, but directly completes to the nearest match before point.
ghc-mod provides some completion for Haskell within Emacs, as well as checking with hlint and ghc. In combination with M-/, it's good enough for me.
haskell-mode currently provides no such possibility. There is some work on implementation of haskell parser for CEDET - in this case, users will get autocompletion features automatically. But this work had started not so much time ago...
My setup is a little more complicated. It uses the auto-complete infrastructure which
shows a dropdown list of candidates automatically similar to traditional IDEs. I downloaded this script that hardcodes all the keywords. In addition to that, I use ghc-mod to generate module names.
As a "cheap and cheerful" autocompletion mechanism, don't overlook M-/. It's completely heuristic and language-independent, but surprisingly effective.
Besides autocompletion for your own code, you can also get autocompletion (with apidocs even) for the standard library, import names, and pragma names using company-ghc. I found this guide to be very helpful. Note, I didn't get it to work fully for myself yet, but I can feel I'm close :-)

Resources