FW: Treating command-line arguments as a Haskell expression

Would someone familiar with the command-line-parsing libraries care to help Krassimir? Thanks Simon -----Original Message----- From: Krassimir Krustev [mailto:krassimir.krustev@gmail.com] Sent: 23 December 2007 11:38 To: Simon Peyton-Jones Subject: Treating command-line arguments as a Haskell expression Dear Dr. Jones: I've been pulling my hair over the Christmas Holidays trying to figure the following: I want to call a function from within Haskell module so that the name of this function corresponds to my first command-line argument and the rest rest of the command-line arguments are would become themselves the argument to this function. Coundn't figure this out. It is my first week with Haskell. Yours, Krassimir

Simon Peyton-Jones:
Would someone familiar with the command-line-parsing libraries care to help Krassimir?
I agree with Max that it looks like the problem is not doing any fancy command-line parsing (if that is indeed the issue, then please post more information about what the problem is). Rather, how to run a function whose name and arguments are given as strings from the command line. Max gave one answer. Another approach, if appropriate, would be to use GHCi. You could do that using the GHC API: http://haskell.org/haskellwiki/GHC/As_a_library (search for "runStmt") Or you could do it using GHCi from the command line and the shell. This is a bit of a hack, but you can get it working in minutes, without installing anything extra. Here's how: The trick is to pass information into GHCi via environment variables, using the .ghci file and the :def command. Place something like the following in the file ".ghci" in the same directory with your program: :def getEnv (\[v,e]->System.Environment.getEnvironment>>=return.maybe""((concat["let ",v,"="]++).show).lookup e).words :getEnv func FUNC :getEnv args ARGS :def run const(return$unwords[func,args]) :run :quit (Watch out for word-wrap in this email message - there needs to be a space after the word "let ", and every line begins with ":") Write a simple shell script that arranges for the name of the function and arguments to be in the environment variables FUNC and ARGS, and then calls ghci. Something like this (assuming you are on something Unix-like): #!/bin/bash export FUNC="$1" shift export ARGS="$*" ghci YourProgram.hs This obviously would have to be tweaked to your specific needs. For example, you'll get the GHCi welcome message at the beginning of your output. So your shell script will have to filter that out if it is not acceptable. Hope this helps, Yitz

As the previous answers show, hooking dynamic evaluation, or a subset thereof, into Haskell is not a particularly easy task. If this is just a program to get up-and-running with understanding Haskell, probably best not to delve into this sorts of stuff? A simpler solution, albeit one which requires some boilerplate, would be to ensure that either all the functions you dispatch to call getArgs themselves (i.e. are of type IO ()) or simply take a list of remaining parameters (i.e. are of type [String] ->IO ()) and then pull them out of either a list or a map. Something resembling this approach is, for example, here: http://haskell.org/haskellwiki/ Simple_unix_tools --S P.S. using Template Haskell to solve this would be a fairly interesting exercise as well, I suspect.

Hi
I want to call a function from within Haskell module so that the name of this function corresponds to my first command-line argument and the rest rest of the command-line arguments are would become themselves the argument to this function.
While you can do this, you probably don't actually want to. You probably have one of two scenarios in mind: 1) You want to test the program. Use ghci or hugs for this, which lets you type in expressions and then evaluates them. 2) You only intend their to be a subset of functions which can be invoked. With higher order functions this is easy: functions = [("foo",foo), ("bar",bar)] main = do (name:cmds) <- getArgs case lookup name functions of Nothing -> putStrLn "Function not found" Just f -> f cmds Thanks Neil Note to the mailing list: When someone says it is their first week of Haskell, answers should probably include phrases like "pattern match" or "higher order" - not Template Haskell, hs-plugins, HList, GADT's etc!
participants (5)
-
Max Vasin
-
Neil Mitchell
-
Simon Peyton-Jones
-
Sterling Clover
-
Yitzchak Gale