Reputation: 7183
When I'm developing some data analyses pipelines in haskell, it often would be useful to preload variable state into GHCi upon loading.
What I end up doing now is copy and pasting parts of a script line-by-line in emacs just to test and check the output of some intermediate processing. I can't even bulk copy-paste code because the line breaks don't get transferred (at least in emacs Interactive-Haskell mode)
Is there a way to do this?
EDIT: simply loading/reloading a .hs file doesn't do the trick because afaik there's no way to have "<-" bindings at the top level.
Upvotes: 3
Views: 766
Reputation: 11963
I suggest you take a look at foreign-store. It allows you to refer to variables by numbers, which persists through reloads. Here is an example:
λ: :set -XScopedTypeVariables
λ: import Foreign.Store
λ: st <- newStore "example"
Loading package foreign-store-0.2 ... linking ... done.
λ: readStore st
"example"
λ: st
Store 0
λ: :r
Ok, modules loaded: none.
λ: st
<interactive>:8:1:
Not in scope: ‘st’
Perhaps you meant ‘fst’ (imported from Prelude)
λ: Just (st :: Store String) <- lookupStore 0
λ: readStore st
"example"
Alternatively, you can also put all your definitions in a single hs file and only reload that. You can use unsafePerformIO to get around the restriction that you cannot use <-
at the top-level. I think that is ok in this case, since your only using it for interactive anyway:
module Example where
import System.IO.Unsafe
example :: String
example = "example"
file :: String
file = unsafePerformIO $ readFile "/tmp/example.hs"
Upvotes: 3
Reputation: 11913
There are two main ways to do this:
:l [filename]
GHCi command to reload a file without exiting GHCi.~/.ghci
file, which will be loaded when GHCi is opened.If you don't know what to put into ~/.ghci
, here's what I have in mine:
:set prompt "\955 "
:set prompt2 "| "
:def hoogle \x -> return $ ":!hoogle --info \"" ++ x ++ "\""
let f `on` x = \a b -> (f a) `x` (f b)
let break (f,g) = \a -> (f a, f g)
Upvotes: 0