34

I've started to teach myself Haskell, and for that I've installed The Haskell Platform for Windows. I'm using WinGHCi as of now. I learned that it has command :cd which is used to change directory. But the question is, how would I know which directory I'm currently in? Without knowing that first why would I want to change directory. I searched a lot but couldn't find the answer.

Please tell me if there is a way to know the current working directory. Preferably I would like to configure the command prompt itself to show the current directory, pretty much like Linux's Console.


Following @Daniel's suggestion, I did these:

  • Since I worked on Windows 7, there is no .ghci file (I think it is for Unix-like OS), so I created a file ghci.conf in C:\Users\Apelles\AppData\Roaming\ghc folder, as it is instructed here.
  • Copy pasted the script from Daniel's answer to ghci.conf.
  • Then I started ghci.exe which is the console-like window. I noticed that it loaded few more modules than it usually used to load before. Here is the snapshot:

enter image description here

As you can see it loads more modules, and the last line says,

Can't parse prompt string. Use Haskell syntax.

What does it mean? Which line is causing problem (from the following script)?

let cur fill = do { cwd <- System.Directory.getCurrentDirectory; return (":set prompt \"" ++ cwd ++ fill ++ " \""); }
:def doprompt (\_ -> cur ">")
:def mycd (\dir -> System.Directory.setCurrentDirectory dir >> cur ">")
:doprompt

Also, if I rename ghci.conf file to some random name, and then start ghci.exe, it loads these modules: enter image description here

As I said before, it loads less number of modules, which means with ghci.conf, ghci.exe does something successfully, but fails at some point. How to fix that?

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • 12
    Try `Prelude> :! pwd` (or whatever Windows' equivalent of pwd is). I think WinGHCi runs an ordinary ghci underneath, so that should work. – Daniel Fischer Jun 28 '12 at 17:56
  • @DanielFischer: That works great. Would it be possible to configure the command prompt itself? – Nawaz Jun 28 '12 at 17:57
  • Yes, you can configure the prompt with `:set prompt Whatever` (type `:?` for a short help on ghci commands). That's per session, however. To make it kind of permanent, do it in your `.ghci` file (I think they're called differently on Windows, don't remember what). I'm not sure how to set it to the current directory, though. – Daniel Fischer Jun 28 '12 at 18:01
  • @DanielFischer: `:set prompt Whatever`? What should I put in place of `Whatever` so that it shows the current working directory? `:set prompt :!pwd` doesn't help here. – Nawaz Jun 28 '12 at 18:05
  • No, indeed it doesn't work that way. I don't know how one would do that, maybe the [users guide](http://www.haskell.org/ghc/docs/7.4.2/html/users_guide/ghci.html) helps. I'm convinced it's possible, but I have never done any such customisation, so I'm afraid I can't help beyond giving general ideas. – Daniel Fischer Jun 28 '12 at 18:31
  • @DanielFischer On Windows, `cd` with no further arguments _prints_ the current directory instead of _setting_ it. – MathematicalOrchid Jun 30 '12 at 14:50
  • @MathematicalOrchid: On Windows, `cd` neither *prints* nor *sets* the current directory. It rather is used to *change directory* (i.e to navigate), hence the name *cd*. – Nawaz Jun 30 '12 at 14:55
  • That it loads more packages with the `ghci.conf` is unsurprising, the dot-ghci uses `System.Directory`, hence the `directory` package and its dependencies have to be loaded. – Daniel Fischer Jun 30 '12 at 16:02
  • @DanielFischer: Yup. That understood immediately seeing them. Actually I wanted to say that it does something successfully, but fails at some point. (edited the question) – Nawaz Jun 30 '12 at 16:03
  • For the "Can't parse prompt string. Use Haskell syntax.", I don't know. Could be something with Windows' path separator. What does `System.Directory.getCurrentDirectory >>= print` output? – Daniel Fischer Jun 30 '12 at 16:04
  • 1
    Unrelated: if it's not too much hassle (and if you don't plan to do development, it isn't I think, there ought to be an installer), you should upgrade to a newer GHC, the current version is 7.4.2. – Daniel Fischer Jun 30 '12 at 16:09
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/13253/discussion-between-daniel-fischer-and-nawaz) – Daniel Fischer Jun 30 '12 at 16:12
  • @Nawaz did you find a solution to this "Current directory scenario"? i started with haskell now and am stuck with the same issue..as a workaround i found that `:cd ` will help. and the WinGHCi starts with the current directory set to where the binary is installed.. Please do let me know if you find out anything. Thanks. – Koushik Shetty Oct 19 '13 at 15:05
  • @Koushik: No. I'm not studying Haskell these says. I will come back to it once I get free time. :-) – Nawaz Oct 19 '13 at 15:12

4 Answers4

32

System.Directory.getCurrentDirectory from the directory package.

Matthias Braun
  • 32,039
  • 22
  • 142
  • 171
jp093121
  • 1,752
  • 19
  • 13
  • 1
    Useful alternative, but should not be the preferred way to do this. This is a call to a language function, which does not help the user learn GHCi's commands. It's like if I asked how to type the letter `~` and you gave me the Alt-code (Type "Alt 126"), instead of telling me to hit the '~' key. – Ryan Jul 18 '19 at 17:56
10

I am not sure if this is the "right" way to do it, but since :! allows shell commands, you can also get it with the appropriate shell command (of your OS) for reading out the directory or the content (so cd, ls and the likes). For example, you can write:

:! cd

It depends what do you need the directory for. If you just want to print it out in your console, then this can help.

All the best!

4

A poor man's solution to set the ghci prompt to the current working directory would be putting

let cur fill = do { cwd <- System.Directory.getCurrentDirectory; return (":set prompt \"" ++ cwd ++ fill ++ " \""); }
:def doprompt (\_ -> cur ">")
:def mycd (\dir -> System.Directory.setCurrentDirectory dir >> cur ">")
:doprompt

in the .ghci file.

In the first line, we define cur :: String -> IO String that gets the current directory and returns the ghci command to set the prompt accordingly. Then we define a ghci command doprompt that performs that action and a command to change directory and set the prompt. The last line executes :doprompt on startup.

Unfortunately, that doesn't make :cd dir reflect the change of directory, one would have to do a manual :doprompt afterwards, or use :mycd to change the directory.

To avoid too long prompts, one could manipulate the result of getCurrentDirectory by dropping an initial part of the file path.

Another drawback to that simple approach is that the prompt doesn't contain information about the loaded modules anymore. I believe all that could be overcome, but I'm not motivated enough to do the digging now.

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
2

In the ghci command prompt type :! cd, it will give you the output for the current directory. In general, use :! followed by shell commands to run any shell command in ghci command prompt. The shells are different on Windows and Mac/Linux, so the commands you can use will be different.

Ryan
  • 1,486
  • 4
  • 18
  • 28
Srijan Chaudhary
  • 637
  • 1
  • 8
  • 18