invoking a Haskell script without a .hs extension

Paul Jarc prj at po.cwru.edu
Sun Aug 17 23:45:30 EDT 2008


I have a Haskell script called "notify", without a .hs extension,
which causes some problems.  (I'm using ghc 6.8.3.)

First attempt: runhaskell notify
Without the .hs extension, ghc doesn't know it's a Haskell script, and
so I get "Could not find module `notify'".  Maybe runhaskell should
automatically add "-x hs" to the ghc command?

Second attempt: runhaskell -x hs notify
This get me "Not in scope: `main'".  runhaskell is invoking ghc with
these arguments:
  -ignore-dot-ghci -x -e ':set prog "hs"' -e ':main ["notify"]' hs
So it looks like runhaskell it treating "-x" as an argument to be
relayed to ghc, "hs" as the name of the script, and "notify" as an
argument to the script.  I guess I need to use "--" to make it clear
where the ghc arguments end and where the script and its arguments
begin.

Third attempt: runhaskell -- -x hs -- notify
This gets me "Not in scope: `main'" again.  runhaskell is invoking ghc
with these arguments:
  -ignore-dot-ghci -x -e ':set prog "hs"' -e ':main ["--","notify"]' hs
This looks like a bug in the "--" handling, unless I'm misinterpreting
the usage message I get from running plain "runhaskell".

Fourth attempt: ghc -ignore-dot-ghci -e ':set prog "notify"' \
  -e ':main []' -x hs notify
This works, but passing arguments becomes rather cumbersome.  If
there's a way to get runhaskell to pass "-x hs" in the right place,
that would be much better.

A somewhat related issue: I'd like to avoid hard-coding the path to
runhaskell or ghc in the #! line.  Instead, I'd like to use #!/bin/sh,
and have the shell find runhaskell or ghc in $PATH.  This means the
first few lines of the script would have to be executed by sh, but
ignored by ghc.  Most scripting langauges have some way of doing this,
although it's often by accident.  The best way I've seen is in Guile,
where "#!" starts a multi-line comment, and "!#" ends it.  For
Haskell, this is the best I could come up with:

#!/bin/sh
{- > /dev/null 2>&1
exec ghc -ignore-dot-ghci \
  -e ":set prog \"$0\"" \
  -e ':main []' -x hs "$0"
-}

But this depends on "{-" not existing as an executable command, or at
least not doing anything harmful when invoked like this.  I'd like to
avoid depending on anything like that.  Does anyone have any better
ideas?


paul


More information about the Glasgow-haskell-users mailing list