8

I am new to Haskell.

I am having a really difficult time outputting command results from GHCi to a file. I was wondering if someone can give me a simple explanation on how to do this? The examples I have found online so far seem over complicated.

recursion.ninja
  • 5,377
  • 7
  • 46
  • 78
AnchovyLegend
  • 12,139
  • 38
  • 147
  • 231

2 Answers2

7

This post on Reddit describes how to colorize your GHCi output (GHC >= 7.6). Instead of a prettyprinter, you could specify a logging function. For example, add the following to your .ghci.conf:

:{
let logFile = "/home/david/.ghc/ghci.log"
    maxLogLength = 1024 -- max length of a single write
    logPrint x = appendFile logFile (take maxLogLength (show x) ++ "\n") >> print x
:}
:set -interactive-print=logPrint

This will log GHCi's output to ghci.log.

  • The logging file must already exist, otherwise appendFile will complain. You'll have to create that manually.

  • It has to fit in a let statement, otherwise GHCi will reject it. Use :{ :} to add multiline support in GHCi.

  • Apparently, using :l gets rid of all imports you've made in your ghci.conf, therefore you're limited to Prelude functions. The Reddit post mentions that you can somehow redefine :l, but I don't know anythng about that. (If you know how to do this, you can of course automatically generate the logfile if it doesn't exist.)

David
  • 8,275
  • 5
  • 26
  • 36
6

Let's suppose you have a function mungeData and you do

 ghci> mungeData [1..5]
 [5,2,5,2,4,6,7,4,6,78,4,7,5,3,57,7,4,67,4,6,7,4,67,4]

writeFile

You can write this to file like this:

ghci> writeFile "myoutput.txt" (show (mungeData [1..5])

I'd be inclined to write

ghci> writeFile "myoutput.txt" $ show $ mungeData [1..5]

to get rid of a few brackets.

Reading it back in

You could get that back using

ghci> fmap (read::String -> [Int]) $ readFile "myoutput.txt"

One number per line

You could output it a line per number like this:

ghci> writeFile "myoutput'.txt" $ unlines.map show $ mungeData [1..5]

which reads back in as

ghci> fmap (map read.lines::String -> [Int]) $ readFile "myoutput'.txt"
AndrewC
  • 32,300
  • 7
  • 79
  • 115
  • Thanks for the reply. This did not work for me. I am getting a parse error. I have a function that adds one to every element of the list. I wrote something like: `writeFile "myoutput.txt" (show(addOne(x)` where x is a list such as 1:2:3:4:5:[] – AnchovyLegend Jan 30 '13 at 03:05
  • You don't need brackets round `x`, and you missed a close bracket. Use: `writeFile "myoutput.txt" (show (addOne x))` – AndrewC Jan 30 '13 at 03:07
  • Thanks for the reply. @AndrewC, what if I am running tests by loading a Tests.hs file, and then typing main in the prompt and hitting enter to execute say 100 test cases. What if I wanted that to be written to a file? Using your method to print out main did not work for me. I appreciate any assistance with this ;) – AnchovyLegend Feb 04 '13 at 00:50
  • 2
    You can either rewrite `main` to write to file instead of to screen or if that's too complicated you can compile it with `ghc Test.hs -O2 -o test.exe` (just `test` on linux/MacOS/unix etc) then redirect its output: `test.exe > testoutput.txt` – AndrewC Feb 04 '13 at 01:29