ghciと通信して補完をする(かなり強引)

とりあえず目処は立った。

でも、他の人に進めようとする気にはなれないな。*1

(defmacro toggle! (name)
  `(progn (setq ,name (not ,name))
		 (message (format "%s:%s" ,(symbol-name name) ,name))))


(require 'inf-haskell)

(defun haskell-send-string (str)
  (condition-case err
      (comint-send-string (get-process "haskell") (format "%s\n" str))
    (error err)))

(defvar haskell-preoutput-filter-functions nil)
(defvar haskell-output-storage nil)
(defvar haskell-connect-inistalled nil)

(defun haskell-connect-cleanup ()
  (setq haskell-output-storage nil))

(defmacro haskell-connect-with-repl (send-func)
  `(let ((haskell-reading-p t)
	 (old-filter comint-preoutput-filter-functions)
	 (comint-preoutput-filter-functions haskell-preoutput-filter-functions))
     (unwind-protect
	 (progn
	   (haskell-connect-cleanup)
	   ,send-func
	   (while haskell-reading-p (sleep-for 0 100))
	   (funcall haskell-output-filter
		    (apply 'concat (reverse haskell-output-storage))))
       (setq comint-preoutput-filter-functions old-filter))))

(defun haskell-repl-running-p () (get-process "haskell"))

(defmacro haskell-filter-function-maker (regexp)
  (let1 s (gensym)
    `(lambda (,s)
       (when (string-match-p ,regexp ,s)
	 (setq haskell-reading-p nil))
       (push ,s haskell-output-storage)
       "")))


(defvar haskell-connect-ask-y-or-n-messages
  '("Display +all +[0-9]+ +possibilities\\? (y or n)" "--More--"))

(defvar haskell-connect-junk-messages
      `("<interactive>:[0-9]+:[0-9]+: parse error on input.*"
	    ,@haskell-connect-ask-y-or-n-messages))

(defun haskell-connect-install () (interactive)
  (when (and (haskell-repl-running-p)
	     (not haskell-connect-inistalled))
    (haskell-send-string ":set prompt \"REPL> \"")
    (toggle! haskell-connect-inistalled)
    (add-hook 'haskell-preoutput-filter-functions
	      (haskell-filter-function-maker "REPL> *$"))
    (add-hook 'haskell-preoutput-filter-functions
	      (lambda (s)
		(when (some (lambda (regexp) (string-match-p regexp s))
			    haskell-connect-ask-y-or-n-messages)
		  (haskell-send-string "y"))
		s))
    (setq haskell-output-filter
	  (lambda (s) (substring-no-properties s 0 -7)))
    ))

実行

(require 'inf-haskell)
(haskell-mode)
(run-haskell)
(haskell-connect-install)
(let1 result (haskell-connect-with-repl (haskell-send-string "\t\t"))
  (loop for regexp in haskell-connect-junk-messages
	do (setq result (replace-regexp-in-string regexp "" result))
	finally return result)) ; => 

;; !!                      Prelude.asTypeOf        Prelude.scanl           fst
;; $                       Prelude.asin            Prelude.scanl1          gcd
;; $!                      Prelude.asinh           Prelude.scanr           getChar
;; &&                      Prelude.atan            Prelude.scanr1          getContents
;; *                       Prelude.atan2           Prelude.seq             getLine
;; **                      Prelude.atanh           Prelude.sequence        head
;; +                       Prelude.break           Prelude.sequence_       id
;; ++                      Prelude.catch           Prelude.show            init
;; -                       Prelude.ceiling         Prelude.showChar        interact
;; .                       Prelude.compare         Prelude.showList        ioError
;; /                       Prelude.concat          Prelude.showParen       isDenormalized
;; /=                      Prelude.concatMap       Prelude.showString      isIEEE
;; <                       Prelude.const           Prelude.shows           isInfinite
;; <=                      Prelude.cos             Prelude.showsPrec       isNaN
;; =<<                     Prelude.cosh            Prelude.significand     isNegativeZero
;; ==                      Prelude.curry           Prelude.signum          iterate
;; >                       Prelude.cycle           Prelude.sin             last
;; >=                      Prelude.decodeFloat     Prelude.sinh            lcm
;; >>                      Prelude.div             Prelude.snd             length
;; >>=                     Prelude.divMod          Prelude.span            lex
;; Bool                    Prelude.drop            Prelude.splitAt         lines
;; Bounded                 Prelude.dropWhile       Prelude.sqrt            log
;; Char                    Prelude.either          Prelude.subtract        logBase
;; Double                  Prelude.elem            Prelude.succ            lookup
;; EQ                      Prelude.encodeFloat     Prelude.sum             map
;; Either                  Prelude.enumFrom        Prelude.tail            mapM
;; Enum                    Prelude.enumFromThen    Prelude.take            mapM_
;; Eq                      Prelude.enumFromThenTo  Prelude.takeWhile       max
;; False                   Prelude.enumFromTo      Prelude.tan             maxBound
;; FilePath                Prelude.error           Prelude.tanh            maximum
;; Float                   Prelude.even            Prelude.toEnum          maybe
;; Floating                Prelude.exp             Prelude.toInteger       min
;; Fractional              Prelude.exponent        Prelude.toRational      minBound
;; Functor                 Prelude.fail            Prelude.truncate        minimum
;; GT                      Prelude.filter          Prelude.uncurry         mod
;; IO                      Prelude.flip            Prelude.undefined       negate
;; IOError                 Prelude.floatDigits     Prelude.unlines         not
;; Int                     Prelude.floatRadix      Prelude.until           notElem
;; Integer                 Prelude.floatRange      Prelude.unwords         null
;; Integral                Prelude.floor           Prelude.unzip           odd
;; Just                    Prelude.fmap            Prelude.unzip3          or
;; LT                      Prelude.foldl           Prelude.userError       otherwise
;; Left                    Prelude.foldl1          Prelude.words           pi
;; Maybe                   Prelude.foldr           Prelude.writeFile       pred
;; Monad                   Prelude.foldr1          Prelude.zip             print
;; Nothing                 Prelude.fromEnum        Prelude.zip3            product
;; Num                     Prelude.fromInteger     Prelude.zipWith         properFraction
;; Ord                     Prelude.fromIntegral    Prelude.zipWith3        putChar
;; Ordering                Prelude.fromRational    Prelude.||              putStr
;; Prelude.!!              Prelude.fst             Rational                putStrLn
;; Prelude.$               Prelude.gcd             Read                    quot
;; Prelude.$!              Prelude.getChar         ReadS                   quotRem
;; Prelude.&&              Prelude.getContents     Real                    read
;; Prelude.*               Prelude.getLine         RealFloat               readFile
;; Prelude.**              Prelude.head            RealFrac                readIO
;; Prelude.+               Prelude.id              Right                   readList
;; Prelude.++              Prelude.init            Show                    readLn
;; Prelude.-               Prelude.interact        ShowS                   readParen
;; Prelude..               Prelude.ioError         String                  reads
;; Prelude./               Prelude.isDenormalized  True                    readsPrec
;; Prelude./=              Prelude.isIEEE          ^                       realToFrac
;; Prelude.<               Prelude.isInfinite      ^^                      recip
;; Prelude.<=              Prelude.isNaN           abs                     rem
;; Prelude.=<<             Prelude.isNegativeZero  acos                    repeat
;; Prelude.==              Prelude.iterate         acosh                   replicate
;; Prelude.>               Prelude.last            all                     return
;; Prelude.>=              Prelude.lcm             and                     reverse
;; Prelude.>>              Prelude.length          any                     round
;; Prelude.>>=             Prelude.lex             appendFile              scaleFloat
;; Prelude.Bool            Prelude.lines           asTypeOf                scanl
;; Prelude.Bounded         Prelude.log             asin                    scanl1
;; Prelude.Char            Prelude.logBase         asinh                   scanr
;; Prelude.Double          Prelude.lookup          atan                    scanr1
;; Prelude.EQ              Prelude.map             atan2                   seq
;; Prelude.Either          Prelude.mapM            atanh                   sequence
;; Prelude.Enum            Prelude.mapM_           break                   sequence_
;; Prelude.Eq              Prelude.max             catch                   show
;; Prelude.False           Prelude.maxBound        ceiling                 showChar
;; Prelude.FilePath        Prelude.maximum         compare                 showList
;; Prelude.Float           Prelude.maybe           concat                  showParen
;; Prelude.Floating        Prelude.min             concatMap               showString
;; Prelude.Fractional      Prelude.minBound        const                   shows
;; Prelude.Functor         Prelude.minimum         cos                     showsPrec
;; Prelude.GT              Prelude.mod             cosh                    significand
;; Prelude.IO              Prelude.negate          curry                   signum
;; Prelude.IOError         Prelude.not             cycle                   sin
;; Prelude.Int             Prelude.notElem         decodeFloat             sinh
;; Prelude.Integer         Prelude.null            div                     snd
;; Prelude.Integral        Prelude.odd             divMod                  span
;; Prelude.Just            Prelude.or              drop                    splitAt
;; Prelude.LT              Prelude.otherwise       dropWhile               sqrt
;; Prelude.Left            Prelude.pi              either                  subtract
;; Prelude.Maybe           Prelude.pred            elem                    succ
;; Prelude.Monad           Prelude.print           encodeFloat             sum
;; Prelude.Nothing         Prelude.product         enumFrom                tail
;; Prelude.Num             Prelude.properFraction  enumFromThen            take
;; Prelude.Ord             Prelude.putChar         enumFromThenTo          takeWhile
;; Prelude.Ordering        Prelude.putStr          enumFromTo              tan
;; Prelude.Rational        Prelude.putStrLn        error                   tanh
;; Prelude.Read            Prelude.quot            even                    toEnum
;; Prelude.ReadS           Prelude.quotRem         exp                     toInteger
;; Prelude.Real            Prelude.read            exponent                toRational
;; Prelude.RealFloat       Prelude.readFile        fail                    truncate
;; Prelude.RealFrac        Prelude.readIO          filter                  uncurry
;; Prelude.Right           Prelude.readList        flip                    undefined
;; Prelude.Show            Prelude.readLn          floatDigits             unlines
;; Prelude.ShowS           Prelude.readParen       floatRadix              until
;; Prelude.String          Prelude.reads           floatRange              unwords
;; Prelude.True            Prelude.readsPrec       floor                   unzip
;; Prelude.^               Prelude.realToFrac      fmap                    unzip3
;; Prelude.^^              Prelude.recip           foldl                   userError
;; Prelude.abs             Prelude.rem             foldl1                  words
;; Prelude.acos            Prelude.repeat          foldr                   writeFile
;; Prelude.acosh           Prelude.replicate       foldr1                  zip
;; Prelude.all             Prelude.return          fromEnum                zip3
;; Prelude.and             Prelude.reverse         fromInteger             zipWith
;; Prelude.any             Prelude.round           fromIntegral            zipWith3
;; Prelude.appendFile      Prelude.scaleFloat      fromRational            ||

*1:汚すぎる