4

I've been attempting to use Haskell for running a simple production process. Like many production processes, it involves changing the states of things all over the place. For this reason, it would be really handy for me to have a script file where I could keep track of things and selectively run commands into interactive Haskell, something like

-- to start the process
process <- startProcess

-- to stop process
stopProcess

-- to check how things are going
summary <- checkStuff
summary 

-- optionally restart bad processes
restartProcesses (getBadProcesses summary)

-- send summary emails
sendSummaryEmails summary ["abunch@ofemails.com", "thatIwould@rather.com", 
                           "nothaveto@keep.com" "typing@out.com",
                           "orcopy@pasting.com"]

-- set up something big that I don't want to have to retype/paste every time
studentGrades <- getStudentGrades "John Peterson"
gen <- getStdGen
let (randomTest, gen') = generateRandomTest studentGrades gen
compilePdf randomTest
answers <- getAnswers
gradeTest randomTest answers "John Peterson"

It would be really cool if, like with ESS (Emacs speaks statistics) in R, if you could press a button to send these lines to the repl process. Maybe seperate buttons for line, paragraph, region. Is there already a way to do this?

For example with ESS, C-Ret sends the line, C-c C-c sends a paragraph, and C-c C-r sends a region.

Mike Flynn
  • 1,025
  • 2
  • 12
  • 29
  • What's keeping you from having a file loaded into the repl with the right commands and parameters? What's keeping you from compiling the code together with a suitable `main` function? – MarLinn Aug 20 '16 at 00:56
  • I don't want to run this code all at once, I want to selectively load it into the repl depending on the current state of the process, and doing that with one keystroke (`C-Ret`) is an order of magnitude performance boost over typing (10-60 keystrokes) and 5x more efficient than copy paste in emacs (about 5 keystrokes). – Mike Flynn Aug 20 '16 at 03:17
  • I also might want to customize how I run the lines on the fly, so coding them into single commands and then reloading the module is also less efficient than just changing the lines in the script and loading them into the buffer. – Mike Flynn Aug 20 '16 at 03:19
  • I see... I don't have an answer to that. But you could still define local functions; if they're one char long it's two keystrokes per instruction. Maybe use `:e` or a self-made command (in `.ghci`) to help editing on the fly – MarLinn Aug 20 '16 at 17:24

1 Answers1

1

This emacs lisp function will send a command to haskell's repl

(defun haskell-send-command (cmd)
  (process-send-string (inferior-haskell-process) (concat cmd "\n")))

and this will call the previous one with the current selection

(defun haskell-send-selection ()
  (interactive)
  (haskell-send-command (x-selection)))

You can assign it a keyboard shortcut with global-set-key. Then you need to figure out how to quickly select what you want to send. For instance M-h is mark-paragraph. Or just recode the ESS functions you like :

(defun haskell-send-paragraph ()
  (interactive)
  (mark-paragraph)
  (haskell-send-selection))

I actually used those to build a small debugging GUI for Haskell in emacs. I have shortcuts for setting breakpoints and stepping, and the position of the debugger highlights directly in the haskell code.

V. Semeria
  • 3,128
  • 1
  • 10
  • 25