This a program I wrote to execute various power-related function on my computer. It accepts one command-line argument that describes what action to take and then performs that action. Usage looks like this:
C:\Users\Noah\My Code\GHCI> power sleep
execute sleep? (y/n)
y
//computer goes to sleep
Here's the code. Any feedback whatsoever is appreciated, regarding either my program's design or the style, formatting and good/bad practices of my code.
--power.hs
import System.Cmd(system)
import System.Environment(getArgs)
type Arg = String --A command-line argument
type Cmd = String --A command to execute
--paths to programs that will carry out the actions
shutdown_path = "C:\\Windows\\System32\\shutdown.exe"
rundll32_path = "C:\\Windows\\System32\\rundll32.exe"
--assoc list mapping arguments to the action that should be taken when that argument is received
cmds :: [(Arg, Cmd)]
cmds = [ ("shutdown", shutdown_path ++ " /s /t 0" ),
("sleep", rundll32_path ++ " powrprof.dll,SetSuspendState 0,1,0"),
("hibernate", shutdown_path ++ " /h" ), -- does not work
("lock", rundll32_path ++ " user32.dll,LockWorkStation" ),
("restart", shutdown_path ++ " -t 0 -r -f" ) ]
--gets the argument passed to the program. Calls error if there is not exactly one argument.
extractCmdOrFail :: IO Arg
extractCmdOrFail = getArgs >>= check
where check [s] = return s
check _ = error "Wrong Number of arguments"
--finds the command to execute from the given command-line arg. Calls error if no command is found.
findCmdOrFail :: Arg -> Cmd
findCmdOrFail s = check $ lookup s cmds
where check (Just s') = s'
check Nothing = error "Unknown command: " ++ s
--prompts the user to confirm whether or not they want to execute the command.
prompt :: Cmd -> Arg -> IO ()
prompt cmd name = putStr ("Execute " ++ name ++ "? (y/n)\n") >> getChar >>= branch cmd
--conditional "loop" that either executes the command, cancels, or awaits valid input.
branch :: Cmd -> Char -> IO ()
branch cmd 'y' = system cmd >> return ()
branch cmd 'n' = putStrLn "Command Cancelled" >> getChar >> return ()
branch cmd _ = getChar >>= branch cmd
--main function
main = extractCmdOrFail >>= (\arg -> prompt (findCmdOrFail arg) arg)