Haskell diagrams: generating SVG without compiling? - haskell

I tried the Fibonacci demo from the diagrams gallery
but, as many of their examples do, it requires compilation and then the mainWith function takes various options, including a file name for SVG output. I'd like to get the same result of an .svg output file, but from within GHCi, without having to compile first.
While this Q&A is about the same issue, the solution there uses API calls that no longer seem to work, such as SizeSpec2D and mkSizeSpec.

You can :load the .lhs file into GHCi and then use the :main command to run it.
$ cd $(mktemp -d)
$ wget -q https://archives.haskell.org/projects.haskell.org/diagrams/gallery/FibCalls.lhs
$ stack ghci --package diagrams-lib diagrams-svg diagrams-contrib
λ> :load FibCalls.lhs
[1 of 1] Compiling Main ( FibCalls.lhs, interpreted )
Ok, one module loaded.
λ> :main -o out.svg
λ> :quit
Leaving GHCi.
$ head -n2 out.svg
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"

Related

Modifying Emacs Inferior Haskell processes to enable CPP processing

If we look at the source of The random package we have a file Random.hs. Because of CPP extensions one has to invoke ghci via the following command :
ghci -cpp Random.hs
Alternatively one can do :
ghci -cpp
and then from within ghci :
Prelude GOA> :load Random
[1 of 1] Compiling System.Random ( Random.hs, interpreted )
Ok, modules loaded: System.Random.
If I use Emacs Inferior Haskell mode (Emacs/Inferior Haskell processes) and I have
the source :
module Main where
import System.Random
gen = (random (mkStdGen 0)) :: (Bool,StdGen)
mymult :: Int -> Int
mymult x = 2 * x
main = do
print $ mymult 5
then upon typing the emacs command :
C-c C-l
which is inferior-haskell-load-file, ghci is opened in a subwindow in emacs. However if from within this window I type load Random.hs then I get the error message :
*Main GOA> :load Random.hs
Random.hs:1:2: lexical error at character 'i'
Failed, modules loaded: none.
How can I load Random.hs taking into account cpp extensions? Or alternatively how do I modify haskell-mode/inf-haskell.el such that ghci is invoked with the -cpp option upon typing C-c C-l, so that the command :load Random.hs can be executed without error?
The most reliable way is certainly to request CPP, along with other extensions, in the file header:
{-# LANGUAGE CPP #-}
#if __GLASGOW_HASKELL__ >= 701
{-# LANGUAGE Trustworthy #-}
#endif
-----------------------------------------------------------------------------
-- |
-- Module : System.Random
-- Copyright : (c) The University of Glasgow 2001
-- License : BSD-style (see the file LICENSE in the 'random' repository)
The random package only does this in the .cabal file.
The easiest way might be to simply turn CCP on permanently in all ghci sessions, by adding
:set -XCPP
to your ~/.ghci file.

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.

Get absolute path of current source file in Haskell

Is it possible to get the absolute path of the current source file in Haskell?
I could only find one relevant function: getCurrentDirectory from System.Directory, but it "returns an absolute path to the current directory of the calling process.", not the path of the current file.
(I need it to read sample inputs which are located in the same folder as the source file; If there's any better way to do it, that will be helpful too!)
You can use CPP. If you compile this file
{-# LANGUAGE CPP #-}
main = print __FILE__
it will print the path to the source as you passed it to ghc – which may or may not be the full path, though:
/tmp $ ghc --make mypath.hs
[1 of 1] Compiling Main ( mypath.hs, mypath.o )
Linking mypath ...
/tmp $ ./mypath
"mypath.hs"
/tmp $ ghc --make /tmp/mypath.hs
Linking /tmp/mypath ...
/tmp $ ./mypath
"/tmp/mypath.hs"
As an alternative, the file-embed package can be used here. It uses template haskell to embed files/directories.
This can be very useful to embed resources or configs in the executable. It may not be advisable to read the sample input this way though. data-files in cabal might be better alternative as already pointed out earlier in this thread.
The PseudoMacros package might be useful. According to the description, it provides C-like strings for the current file name etc.
UPDATE
The file name returned by PseudoMacros equals the path passed to ghc (same behaviour as #JoachimBreitner mentioned in his answer), so
import PseudoMacros
main :: IO ()
main = putStrLn ("Hello from " ++ $__FILE__ ++ ", line " ++ show $__LINE__ ++ "!")
will print
Hello from tmp.hs, line 5!
or
Hello from /tmp/tmp.hs, line 5!
depending on whether you provided a relative or absolute filename to ghc.

Redirecting Haskell GHCi output to text file [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Outputting Haskell GHCi command results to a txt file
I am new to Haskell and I am trying to redirect test cases output results to a text file. The way it is set up now, is a AddAllTestCases.hs contains all the test cases I need to run in order to test a function I created. I run the test cases on GHCi by loading AddAllTestCases.hs and then simply typing main and hitting enter. That causes test case output results to print inside the GHCi perfectly.
Because there hundreds of test cases, I need to redirect output results to text file.
Attempt #1:
writeFile "myoutput.txt" $ show $ main
I get the following error:
No instance for (Show(IO())) arising from a use of show
Attempt #2 in CMD (trying to create an executable, then outputting executable results to text file):
ghc --make AddAllTests.hs -o testResults.exe
Which gives me the following error:
Warning: output was redirected with -o, but no output will be generated because there is no Min module
This is weird because when I am using GHCi (attempt #1) and I type in main it executes everything perfectly, which I would assume, implies that there is a main module?
I greatly appreciate any help with redirecting test case results to a text file.
Many thanks in advance!
You need a Main module (and a main action) to produce an executable. You can rename your module to Main, or you can specify the module to be considered Main on the command line,
ghc --make -main-is AddAllTests AddAllTests.hs -o testResults.exe
to produce an executable without a module named Main.
A method without compiling would be
ghc AddAllTests.hs -e "main" > testResults.txt
Another method would be to have a file in which you just list all test cases,
3 + 2 :: Rational
reverse "foobar"
:q
and run ghci with redirected in- and output
ghci < testCases > testResults.txt

How do you get GHC to output compile errors to a file instead of standard output?

I'm trying to compile a haskell file that has a HUGE number of errors in it. I want to start debugging the first one but unfortunately there are so many that they go off the screen.
I want to pipe the error messages to a file so that I can read from the top, but normal methods don't seem to work.
I've tried:
ghc File.hs > errors.log
ghc File.hs >> errors.log
ghc File.hs | more
None of them work. Using > and >> only writes the first couple of lines to the file and then the rest to standard output. Using more, less, cat etc doesn't make any difference at all.
Is there a flag for GHC that will let me output to a file?
(I should probably let you know that I'm working on a Windows machine with Cygwin.)
Most programs write output to the standard output (file descriptor 1) and error messages to the standard error (file descriptor 2).
You can ask your shell to redirect the standard error to another location like this:
ghc File.hs > output.log 2> errors.log
or if you want them in the same file:
ghc File.hs > output.log 2>&1
See your shell's manpage section of redirections for full details. Note that the shells are picky about the order of the redirections.
You can also view the output directly, using the same redirect as sarnold's solution, but without the intermediate output file:
ghc File.hs 2>&1 | less
(same goes for more instead of less, etc.)

Resources