diff --git a/Mueval/Concurrent.hs b/Mueval/Concurrent.hs
--- a/Mueval/Concurrent.hs
+++ b/Mueval/Concurrent.hs
@@ -39,10 +39,11 @@
                            hSetBuffering stdout NoBuffering
 
                       -- Our modules and expression are set up. Let's do stuff.
-                           forkIO (interpreterSession typeprint mdls expr
+                           forkIO (interpreterSession typeprint extend mdls expr
                                                      `catchDyn` (printInterpreterError)
                                                                     >> putMVar mvar "Done.")
           where mdls = modules opts
                 expr = expression opts
                 tout = timeLimit opts
                 typeprint = printType opts
+                extend = extensions opts
diff --git a/Mueval/Interpreter.hs b/Mueval/Interpreter.hs
--- a/Mueval/Interpreter.hs
+++ b/Mueval/Interpreter.hs
@@ -6,16 +6,19 @@
 
 import Language.Haskell.Interpreter.GHC (eval, newSession, reset, setImports,
                                          setOptimizations, setUseLanguageExtensions, setInstalledModsAreInScopeQualified,
-                                                         typeChecks, typeOf, withSession,
+                                         typeChecks, typeOf, withSession,
                                          Interpreter, InterpreterError, ModuleName, Optimizations(All))
 
+import qualified Codec.Binary.UTF8.String as Codec (decodeString)
+import qualified System.IO.UTF8 as UTF (putStr)
+
 import qualified Mueval.Resources (limitResources)
 
 -- | From inside the Interpreter monad, print the String (presumably the result
 -- of interpreting something), but only print the first 1024 characters to avoid
 -- flooding. Lambdabot has a similar limit.
 say :: String -> Interpreter ()
-say = liftIO . putStr . take 1024
+say = liftIO . UTF.putStr . Codec.decodeString . take 1024
 
 -- | Oh no, something has gone wrong. Call 'error' and then, as with 'say',
 -- print out a maximum of 1024 characters.
@@ -27,18 +30,24 @@
    optimizations, hide all packages, make sure one cannot call unimported
    functions, typecheck (and optionally print it), set resource limits for this
    thread, and do some error handling. -}
-interpreter :: Bool -> [ModuleName] -> String -> Interpreter ()
-interpreter prt modules expr = do
-                                  setUseLanguageExtensions True -- Don't trust the
-                                                                -- extensions
+interpreter :: Bool -> Bool -> [ModuleName] -> String -> Interpreter ()
+interpreter prt exts modules expr = do
+                                  setUseLanguageExtensions exts -- False by default
+
                                   setOptimizations All -- Maybe optimization will make
-                                                       -- more programs terminate.
+                                                       -- more programs
+                                                       -- terminate.
+
                                   reset -- Make sure nothing is available
                                   setInstalledModsAreInScopeQualified False
+
                                   setImports modules
+                                  if prt then say $ expr ++ "\n" else return ()
 
-                                  checks <- typeChecks expr
                                   liftIO Mueval.Resources.limitResources
+
+                                  checks <- typeChecks expr
+
                                   if checks then do
                                               if prt then do say =<< typeOf expr
                                                              say "\n"
@@ -50,10 +59,11 @@
 -- | Wrapper around 'interpreter'; supplies a fresh GHC API session and
 -- error-handling. The arguments are simply passed on.
 interpreterSession :: Bool -- ^ Whether to print inferred type
+                   -> Bool -- ^ Whether to use GHC extensions
                    -> [ModuleName] -- ^ A list of modules we wish to be visible
                    -> String -- ^ The string to be interpreted as a Haskell expression
                    -> IO ()  -- ^ No real result, since printing is done deeper in
                             -- the stack.
-interpreterSession prt mds expr = Control.Exception.catch
-                                  (newSession >>= (flip withSession) (interpreter prt mds expr))
+interpreterSession prt exts mds expr = Control.Exception.catch
+                                  (newSession >>= (flip withSession) (interpreter prt exts mds expr))
                                   (\_ -> error "Expression did not compile.")
diff --git a/Mueval/ParseArgs.hs b/Mueval/ParseArgs.hs
--- a/Mueval/ParseArgs.hs
+++ b/Mueval/ParseArgs.hs
@@ -1,8 +1,12 @@
 module Mueval.ParseArgs (Options(..), interpreterOpts, getOptions) where
 
+import Control.Monad (liftM)
 import System.Console.GetOpt
 import System.Environment (getArgs)
 
+import qualified System.IO.UTF8 as UTF (putStr)
+import qualified Codec.Binary.UTF8.String as Codec (decodeString)
+
 import Mueval.Context (defaultModules)
 
 -- | See the results of --help for information on what each option means.
@@ -12,6 +16,7 @@
    , expression :: String
    , user :: String
    , printType :: Bool
+   , extensions :: Bool
  } deriving Show
 
 defaultOptions :: Options
@@ -19,7 +24,8 @@
                            , modules = defaultModules
                            , timeLimit = 5
                            , user = ""
-                           , printType = False }
+                           , printType = False
+                           , extensions = False }
 
 options :: [OptDescr (Options -> Options)]
 options = [Option ['p']     ["password"]
@@ -31,12 +37,15 @@
            Option ['m']     ["module"]
                       (ReqArg (\m opts -> opts { modules = m:(modules opts) }) "MODULE")
                       "A module we should import functions from for evaluation. (Can be given multiple times.)",
+           Option ['E']     ["Extensions"]
+                      (NoArg (\opts -> opts { extensions = True}))
+                      "Whether to enable the Glasgow extensions to Haskell '98. Defaults to false, but enabling is useful for QuickCheck.",
            Option ['e']     ["expression"]
                       (ReqArg (\e opts -> opts { expression = e}) "EXPRESSION")
                       "The expression to be evaluated.",
            Option ['i']     ["inferred-type"]
                       (NoArg (\opts -> opts { printType = True}))
-                      "Whether to enable printing of inferred type. Defaults to false." ]
+                      "Whether to enable printing of inferred type and the expression (as Mueval sees it). Defaults to false." ]
 
 interpreterOpts :: [String] -> IO (Options, [String])
 interpreterOpts argv =
@@ -45,8 +54,9 @@
           (_,_,er) -> ioError $ userError (concat er ++ usageInfo header options)
       where header = "Usage: mueval [OPTION...] --expression EXPRESSION..."
 
--- | Just give us the end result options; this handles I/O and parsing for us.
+-- | Just give us the end result options; this handles I/O and parsing for
+-- us. Bonus points for handling UTF.
 getOptions :: IO Options
-getOptions = do input <- getArgs
+getOptions = do input <- liftM (map Codec.decodeString) getArgs
                 (opts,_) <- interpreterOpts $ input
                 return opts
diff --git a/mueval.cabal b/mueval.cabal
--- a/mueval.cabal
+++ b/mueval.cabal
@@ -1,5 +1,5 @@
 name:                mueval
-version:             0.4.6
+version:             0.5
 
 license:             BSD3
 license-file:        LICENSE
@@ -28,13 +28,13 @@
 data-files:          README
 extra-source-files:  build.sh, tests.sh
 
-Library
+library
         exposed-modules:     Mueval.Concurrent, Mueval.Context, Mueval.Interpreter,
                              Mueval.ParseArgs, Mueval.Resources
-        build-Depends:       base, directory, mtl, unix, hint>=0.2.3, show
+        build-depends:       base, directory, mtl, unix, hint>=0.2.4, show>=0.2, utf8-string
         ghc-options:         -Wall -static
 
-Executable mueval
+executable mueval
            main-is:       main.hs
            build-depends: base
            ghc-options:   -Wall -threaded -static
diff --git a/tests.sh b/tests.sh
--- a/tests.sh
+++ b/tests.sh
@@ -2,9 +2,7 @@
 # tests
 
 # Save typing
-m () { mueval --expression "$@"; }
-# Redefine a failed command to be successful
-mf () { m "$@" || return 0; }
+m () { mueval --inferred-type --expression "$@"; }
 
 # Abort if any commands aren't successful
 set -e
@@ -26,29 +24,36 @@
 m 'tail $ take 50 $ repeat "foo"' --module Data.List --timelimit 3
 ## This tests whether the SimpleReflect stuff is working. Output should be: "(f 1 (f 2 (f 3 (f 4 (f 5 z)))))\"
 m 'foldr (\x y -> concat ["(f ",x," ",y,")"]) "z" (map show [1..5])'
+## Test 1024-char limit
+m 'repeat 1'
+## Let's see whether the ShowQ instances for QuickCheck work
+m 'myquickcheck (1+1 == 2)' -E
+m 'myquickcheck (\x -> x == x)' -E
+m 'let (ñ) = (+) in ñ 5 5'
+echo "\nOK, all the valid expressions worked out well." &&
 
 # Test on bad or outright evil expressions
-echo "\n Now let's test various misbehaved expressions \n" &&
+echo "Now let's test various misbehaved expressions \n" &&
 ## test infinite loop
-mf 'let x = x in x'
-mf 'let x y = x 1 in x 1' --timelimit 3
-mf 'let x = x + 1 in x'
+m 'let x = x in x' ||
+m 'let x y = x 1 in x 1' --timelimit 3 ||
+m 'let x = x + 1 in x' ||
 ## Similarly, but with a strict twist
-mf 'let f :: Int -> Int; f x = f $! (x+1) in f 0'
+m 'let f :: Int -> Int; f x = f $! (x+1) in f 0' ||
 ## test stack limits
-mf 'let x = 1 + x in x'
+m 'let x = 1 + x in x' ||
 ## Let's stress the time limits
-mf 'let {p x y f = f x y; f x = p x x} in f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f f)))))))))))))))))) f'
+m 'let {p x y f = f x y; f x = p x x} in f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f f)))))))))))))))))) f' ||
 ## Now let's test the module whitelisting
-mf 1+1 --module Data.List --module System.IO.Unsafe --module Control.Monad
-mf "let foo = unsafePerformIO readFile \"/etc/passwd\" in foo" --module System.IO.Unsafe
-mf "head [1..]" --module Data.List --module Text.HTML.Download
+m 1+1 --module Data.List --module System.IO.Unsafe --module Control.Monad ||
+m "let foo = unsafePerformIO readFile \"/etc/passwd\" in foo" --module System.IO.Unsafe ||
+m "head [1..]" --module Data.List --module Text.HTML.Download ||
 ### Can we bypass the whitelisting by fully qualified module names?
-mf "Foreign.unsafePerformIO $ readFile \"/etc/passwd\""
-mf "Data.ByteString.Internal.inlinePerformIO $ readFile \"/etc/passwd\""
+m "Foreign.unsafePerformIO $ readFile \"/etc/passwd\"" ||
+m "Data.ByteString.Internal.inlinePerformIO $ readFile \"/etc/passwd\"" ||
 ## We need a bunch of IO tests, but I guess this will do for now.
-mf "let foo = readFile \"/etc/passwd\" >>= print in foo"
-mf "writeFile \"tmp.txt\" \"foo bar\""
+m "let foo = readFile \"/etc/passwd\" >>= print in foo" ||
+m "writeFile \"tmp.txt\" \"foo bar\"" ||
 ## Evil array code, should fail (but not with a segfault!)
-mf  "array (0::Int, maxBound) [(1000000,'x')]" --module Data.Array
+m  "array (0::Int, maxBound) [(1000000,'x')]" --module Data.Array ||
 echo "Done, apparently successfully"
