How to run GHCi in command line like a regular shell command - haskell

Is there any way I can run GHCi on command line like a regular command in shell?
For example: :browse in GHCi - list all the function for specific module.
but I want to run it on shell, e.g.: ghci --browse "MyModule"
which lists all the functions for the module
I know hoogle can run it on shell, e.g: hoogle Monad

The easiest way is to pipe in the commands via standard input. In Bash this can be done nicely with a “here-string”:
$ ghci <<< ':t reverse'
GHCi, version 8.2.1: http://www.haskell.org/ghc/ :? for help
Loaded GHCi configuration from /home/sagemuej/.ghci
Loaded GHCi configuration from /home/sagemuej/.ghc/ghci.conf
Prelude> reverse :: [a] -> [a]
Prelude> Leaving GHCi.
Use verbosity 0 to avoid all the greeting stuff:
$ ghci -v0 <<< ':t reverse'
reverse :: [a] -> [a]

Related

How can I run a GHCi statement in cabal v2-repl directly from command line?

How can I replicate ghci -e "print 123" in cabal v2-repl?
I've searched for "expression" or "statement" in cabal v2-repl --help with no luck.
The simplest way is to use shell piping capabilities. See:
% cabal v2-repl <<< ':type zip'
...
λ zip :: [a] -> [b] -> [(a, b)]
λ Leaving GHCi.
This <<< notation, in sh script interpreter, means that the quoted string is sent to the standard input of the command, followed by newline, then end of file.
There are other ways. For example, if you wish to supply more lines, you can use the so-called "here-doc":
% cabal repl <<EOF
:type zip
:type fst
EOF
The <<< notation is a shorthand for a one-line "here-doc".
In general, a program may know whether its standard input is a terminal (assuming, live user) or a file (which heredoc pretends to be), and behave differently. But ordinarily it would work either way, and, if you can send things to its standard input, you can automate it.

Change shell used to run "shell commands" in GHCi

In GHCi, a shell command can be executed using :!<command>. By default, it seems that the sh shell is used:
Prelude> :!echo $0
/bin/sh
I have a number of aliases and custom functions defined for the shell I use generally on my system (fish), and I'd like to use these from GHCi but not have to translate them into sh-compatible versions.
Is there a way of changing the shell GHCi uses to execute :! commands? I haven't been able to find any :set options for this, nor any command-line arguments to GHCi to do this.
The :! command in current versions of ghci is a call to System.Process.system
-- | Entry point for execution a ':<command>' input from user
specialCommand :: String -> InputT GHCi Bool
specialCommand ('!':str) = lift $ shellEscape (dropWhile isSpace str)
-- [...]
shellEscape :: String -> GHCi Bool
shellEscape str = liftIO (system str >> return False)
I suspect system is hardcoded to /bin/sh, but there's no reason you can't define your own ghci command to do fish calls. I don't have fish installed, so I'll use bash as an example:
λ import System.Process (rawSystem)
λ :def bash \cmd -> rawSystem "/bin/bash" ["-c", cmd] >> return ""
λ :bash echo $0
/bin/bash

Is it possible to pass command line arguments when running Haskell code with `ghc -e`?

Intuitively, I've tried
$ ghc -e "import System.Environment" -e "getArgs" -- a b c
ghc: unrecognised flag: --
did you mean one of:
-n
-F
-v
Usage: For basic information, try the `--help' option.
$
...without success.
I was expecting the output to be along the lines of ["a","b","c"].
The docs here don't seem to mention any way to pass cli arguments through.
AFAIK piping in stdio works as expected.
And perhaps if it is not possible to pass in arguments with ghc -e, maybe it's still possible with ghci to supply both some code, some arguments to it, run, then exit?
To answer the second part of the question:
Prelude> :help :main
Commands available from the prompt:
…
:main [<arguments> ...] run the main function with the given arguments
…
Prelude> let main = System.Environment.getArgs >>= print
Prelude> :main foo bar
["foo","bar"]

What's the right way to :reload and run :main as a single command in GHCi?

Is there a way to chain :reload/:r along with :main as a single command in GHCi?
The goal here is to avoid typing both every time I change something in my other terminal, but to just type ↑Enter.
:cmd seems to accept string with multiple lines.
Therefore you can do the following command.
:cmd return $ unlines [":reload",":main"]
also you can add following code to ~/.ghci
:def hoge const $ return $ unlines [":reload",":main"]
now you can execute :hoge in ghci

latexpdf-esque functionality in haskell?

My haskell program produces .tex output using my own module.
I can't see my way around having to run 'pdflatex' everytime I want to see a result. I can hardly believe this cannot be done in a more direct manner;
Is there a way to have my code compile the .tex-file?
Is the System.Process package what you are looking for? You can use the function
system :: String -> IO ExitCode
to perform system calls.
$ touch tempfile.txt
$ ghci
GHCi, version 7.6.3: http://www.haskell.org/ghc/ :? for help
>> import System.Process
>> system "ls"
tempfile.txt
ExitSuccess
Not particularly idiomatic, but it gets the job done.

Resources