diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,14 @@
+shell-monad (0.6.3) unstable; urgency=medium
+
+  * Add Applicative instance for Script. (Thanks, Abhinav Gupta)
+  * Add IsString instance for Quoted Text. (Thanks, Abhinav Gupta)
+  * Add newVarFrom. (Thanks, Abhinav Gupta)
+  * Fixed "test (foo)" to generate shell code "test ( foo )", where
+    before it had generated the invalid shell code "test (foo)".
+    (Thanks, Ville)
+
+ -- Joey Hess <id@joeyh.name>  Sat, 14 Mar 2015 13:38:13 -0400
+
 shell-monad (0.6.2) unstable; urgency=medium
 
   * Avoid using $_ as this doesn't work in bash.
diff --git a/Control/Monad/Shell.hs b/Control/Monad/Shell.hs
--- a/Control/Monad/Shell.hs
+++ b/Control/Monad/Shell.hs
@@ -1,4 +1,7 @@
 -- | This is a shell monad, for generating shell scripts.
+--
+-- The emphasis is on generating shell code that will work in any POSIX
+-- compliant shell.
 
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE FlexibleInstances #-}
@@ -31,6 +34,7 @@
 	NameHinted,
 	static,
 	newVar,
+	newVarFrom,
 	newVarContaining,
 	setVar,
 	globalVar,
@@ -108,7 +112,7 @@
 	deriving (Eq, Ord, Show)
 
 simpleVar :: forall a. VarName -> Term Var a
-simpleVar name = VarTerm $ V
+simpleVar name = VarTerm V
 	{ varName = name
 	-- Used to expand the variable; can be overridden for other
 	-- types of variable expansion.
@@ -119,9 +123,16 @@
 	, expandVar = \_ (VarName n) -> Q ("$" <> n)
 	}
 
--- | Treats the Text as a glob, which expands to one parameter per
+-- | Treats the Text as a glob.
+--
+-- When used as a 'Param' to a command, it expands to one parameter per
 -- matching file.
 --
+-- > forCmd (cmd "ls" (glob "*/*.cabal")) $ \file ->
+-- >     cmd "echo" file
+--
+-- When used in a 'caseOf', it matches text against the glob.
+--
 -- The input is assumed to be a well-formed glob. Characters in it that
 -- are not alphanumeric and are not wildcard characters will be escaped
 -- before it is exposed to the shell. This allows eg, spaces in globs.
@@ -185,6 +196,13 @@
 newtype Script a = Script (Env -> ([Expr], Env, a))
 	deriving (Functor)
 
+instance Applicative Script where
+	pure a = Script $ \env -> ([], env, a)
+	Script f <*> Script a = Script $ \env0 ->
+		let (expr1, env1, f') = f env0
+		    (expr2, env2, a') = a env1
+		in  (expr1 <> expr2, env2, f' a')
+
 instance Monad Script where
         return ret = Script $ \env -> ([], env, ret)
         a >>= b = Script $ \start -> let
@@ -257,7 +275,7 @@
 	go (Pipe e1 e2) = go e1 <> " | " <> go e2
 	go (And e1 e2) = go e1 <> " && " <> go e2
 	go (Or e1 e2) = go e1 <> " || " <> go e2
-	go (Redir e r) = let use = (\t -> go e <> " " <> t) in case r of
+	go (Redir e r) = let use t = go e <> " " <> t in case r of
 		(RedirToFile fd f) ->
 			use $ redirFd fd (Just stdOutput) <> "> " <> L.pack f
 		(RedirToFileAppend fd f) ->
@@ -289,7 +307,7 @@
 -- Redirections have a default Fd; for example, ">" defaults to redirecting
 -- stdout. In this case, the file descriptor number does not need to be
 -- included.
-redirFd :: Fd -> (Maybe Fd) -> L.Text
+redirFd :: Fd -> Maybe Fd -> L.Text
 redirFd fd deffd
 	| Just fd == deffd = ""
 	| otherwise = showFd fd
@@ -348,7 +366,7 @@
 
 -- | A Param is anything that can be used as the parameter of a command.
 class Param a where
-	toTextParam :: a -> (Env -> L.Text)
+	toTextParam :: a -> Env -> L.Text
 
 -- | Text arguments are automatically quoted.
 instance Param L.Text where
@@ -359,7 +377,7 @@
 	toTextParam = toTextParam . L.pack
 
 instance Param UntypedVar where
-	toTextParam v = \env -> "\"" <> getQ (expandVar v env (varName v)) <> "\""
+	toTextParam v env = "\"" <> getQ (expandVar v env (varName v)) <> "\""
 
 instance Param (Term Var a) where
 	toTextParam (VarTerm v) = toTextParam v
@@ -378,13 +396,13 @@
 
 -- | Allows passing the output of a command as a parameter.
 instance Param Output where
-	toTextParam (Output s) = \env ->
+	toTextParam (Output s) env =
 		let t = toLinearScript $ fst $ runScript env s
 		in "\"$(" <> t <> ")\""
 
 -- | Allows passing an Arithmetic Expression as a parameter.
 instance Param Arith where
-	toTextParam a = \env -> 
+	toTextParam a env =
 		let t = fmtArith env a
 		in "\"" <> t <> "\""
 
@@ -440,7 +458,7 @@
 -- To provide a naming hint, use either 'NamedLike'.
 --
 -- @
--- v1 <- 'newVar' ('NamedLike' "x")
+-- v1 <- 'newVar' ('NamedLike' \"x\")
 -- @
 class NameHinted h where
 	hinted :: (Maybe L.Text -> a) -> h -> a
@@ -472,6 +490,35 @@
 	v <- newVarUnsafe namehint
 	Script $ \env -> ([Cmd (getName v <> "=" <> value)], env, v)
 
+-- | Creates a new shell variable with an initial value coming from any
+-- 'Param'.
+--
+-- For example,
+--
+-- > packageName <- newVarFrom
+-- >      (Output $
+-- >          cmd "grep" "-i" "name\\s*:" (glob "*.cabal") -|-
+-- >          cmd "perl" "-pe" "s/^name\\s*:\\s*//i")
+-- >      (NamedLike "packageName")
+--
+-- Use this with 'WithVar' to store to modified value of a variable in a new
+-- variable.
+--
+-- > home <- globalVar "HOME"
+-- > cabalDir <- newVarContaining (WithVar home (<> "/.cabal")) ()
+-- 
+-- Or to capture the output of an arithmetic operation.
+--
+-- > sum <- newVarFrom (val x `APlus` 1) ()
+--
+newVarFrom
+	:: (NameHinted namehint, Param param)
+	=> param -> namehint -> Script (Term Var t)
+newVarFrom param namehint = do
+	v <- newVarUnsafe namehint
+	Script $ \env ->
+		([Cmd (getName v <> "=" <> toTextParam param env)], env, v)
+
 -- | Creates a new shell variable, with an initial value which can
 -- be anything that can be shown.
 --
@@ -729,6 +776,12 @@
 -- | Matches the value of the Var against the Quoted Text (which can
 -- be generated by 'glob'), and runs the Script action associated
 -- with the first match.
+--
+-- > arg <- takeParameter ()
+-- > caseOf arg
+-- >   [ (quote "-h", showHelp)
+-- >   , (glob "-*", cmd "echo" "Unknown option:" arg)
+-- >   ]
 caseOf :: forall a. Term Var a -> [(Quoted L.Text, Script ())] -> Script ()
 caseOf _ [] = return ()
 caseOf v l = go True l
@@ -743,7 +796,7 @@
 	-- > : ;; *) :
 	-- >     echo default
 	-- > : ;; esac
-	go _ [] = add $ Cmd $ ";; esac"
+	go _ [] = add $ Cmd ";; esac"
 	go atstart ((t, s):rest) = do
 		env <- getEnv
 		let leader = if atstart
@@ -768,7 +821,7 @@
 readVar v = add $ Cmd $ "read " <> getQ (quote (getName v))
 
 -- | By default, shell scripts continue running past commands that exit
--- nonzero. Use "stopOnFailure True" to make the script stop on the first
+-- nonzero. Use 'stopOnFailure True' to make the script stop on the first
 -- such command.
 stopOnFailure :: Bool -> Script ()
 stopOnFailure b = add $ Cmd $ "set " <> (if b then "-" else "+") <> "e"
@@ -915,7 +968,7 @@
 	go (TFileNonEmpty p) = unop "-s" (pv p)
 	go (TFileExecutable p) = unop "-x" (pv p)
 
-	paren t = "\\(" <> t <> "\\)"
+	paren t = "\\( " <> t <> " \\)"
 	
 	binop a o b = paren $ a <> " " <> o <> " " <> b
 	unop o v = paren $ o <> " " <> v
@@ -1073,7 +1126,7 @@
 	pred a = AMinus a (ANum 1)
 	toEnum = ANum . fromIntegral
 	enumFrom a = a : enumFrom (succ a)
-	enumFromThen a b = a : enumFromThen b ((b `AMult` (ANum 2)) `AMinus` a)
+	enumFromThen a b = a : enumFromThen b ((b `AMult` ANum 2) `AMinus` a)
 	fromEnum = error "fromEnum not implemented for Arith"
 	enumFromTo = error "enumFromTo not implemented for Arith"
 	enumFromThenTo = error "enumFromToThen not implemented for Arith"
diff --git a/Control/Monad/Shell/Quote.hs b/Control/Monad/Shell/Quote.hs
--- a/Control/Monad/Shell/Quote.hs
+++ b/Control/Monad/Shell/Quote.hs
@@ -12,6 +12,7 @@
 ) where
 
 import qualified Data.Text.Lazy as L
+import Data.String
 import Data.Monoid
 import Data.Char
 
@@ -52,3 +53,6 @@
 
 -- | An arbitrary value.
 newtype Val v = Val v
+
+instance IsString (Quoted L.Text) where
+	fromString = quote
diff --git a/shell-monad.cabal b/shell-monad.cabal
--- a/shell-monad.cabal
+++ b/shell-monad.cabal
@@ -1,5 +1,5 @@
 Name: shell-monad
-Version: 0.6.2
+Version: 0.6.3
 Cabal-Version: >= 1.8
 License: BSD3
 Maintainer: Joey Hess <id@joeyh.name>
