问题
My goal is to pipe some steps for ghci
to run from a bash script and then exit cleanly. The commentary online says to use runhaskell
for this.
This is the command I'm trying to run:
ghci> import System.Random
ghci> random (mkStdGen 100) :: (Int, StdGen)
With expected result similar to:
(-3633736515773289454,693699796 2103410263)
When I drop this into a file randomtest.hs
and execute it with runhaskell
I get the following error:.
randomtest.hs:3:1: error:
Invalid type signature: random (mkStdGen 100) :: ...
Should be of form <variable> :: <type>
It seems I can't use the runhaskell
method to blindly execute ghci
inputs.
Now the way to work around this is to add extra commands to the file that is passed to runhaskell
:
main = do print (random (mkStdGen 100) :: (Int, StdGen))
My goal is to automate the running of ghci work for a haskell course I'm using. I want to be able to run the ghci command from a bash script - in the format that ghci expects, and have it cleanly exit from ghci (or whatever runs it).
My question is: Is there a way to script a ghci session?
回答1:
You'll want to use expect for that, it allows you to interactively control a REPL with simple commands. This script does what you want:
#!/usr/bin/env expect
log_user 0
spawn ghci
log_user 1
expect ".*> "
send ":set prompt \"ghci> \"\n"
expect "ghci> "
send "import System.Random\n"
expect "ghci> "
send "random (mkStdGen 100) :: (Int, StdGen)\n"
interact
Running this gives you the following:
$ ./ghci-interactive
GHCi, version 8.0.2: http://www.haskell.org/ghc/ :? for help
Prelude> :set prompt "ghci> "
ghci> import System.Random
ghci> random (mkStdGen 100) :: (Int, StdGen)
(-3633736515773289454,693699796 2103410263)
ghci>
Note: You might need to adjust this a bit to be resistant to users setting the prompt in ~/.ghci
.
回答2:
Thanks @SilvanMosberger - you solved the issue so I'll leave yours as correct.
I wanted to generalise this approach so it could load instructions specified in a file - eg RandomPair.ghci
with the following contents:
import System.Random
random (mkStdGen 100) :: (Int, StdGen)
random (mkStdGen 949488) :: (Float, StdGen)
random (mkStdGen 949488) :: (Bool, StdGen)
random (mkStdGen 949488) :: (Integer, StdGen)
Now a script to run this looks like the file RandomPair-ghci.bash
#!/usr/bin/env expect
log_user 0
spawn ghci
log_user 1
expect ".*> "
send ":set prompt \"ghci> \"\n"
set f [open "RandomPair.ghci"]
set replcommands [split [read $f] "\n"]
close $f
foreach replcommand $replcommands {
set replcommand1 [string map {"\"" "\\\""} $replcommand]
expect "ghci> "
send -- "$replcommand1 \n"
}
expect "ghci> "
send ":quit\n"
interact
This gives a result similar to:
$ ./RandomPair-ghci.bash
GHCi, version 8.0.1: http://www.haskell.org/ghc/ :? for help
Prelude> :set prompt "ghci> "
ghci> import System.Random
ghci>
ghci>
ghci> random (mkStdGen 100) :: (Int, StdGen)
(-3633736515773289454,693699796 2103410263)
ghci> random (mkStdGen 949488) :: (Float, StdGen)
(0.3718226,1597344447 1655838864)
ghci> random (mkStdGen 949488) :: (Bool, StdGen)
(False,1485632275 40692)
ghci> random (mkStdGen 949488) :: (Integer, StdGen)
(9159618695640234475,587416689 2103410263)
ghci>
ghci>
ghci> :quit
Leaving GHCi.
$
来源:https://stackoverflow.com/questions/47735327/is-there-a-way-to-script-a-ghci-session