diff --git a/src/Turtle/Format.hs b/src/Turtle/Format.hs
--- a/src/Turtle/Format.hs
+++ b/src/Turtle/Format.hs
@@ -57,6 +57,7 @@
     , e
     , g
     , s
+    , fp
 
     -- * Utilities
     , repr
@@ -67,6 +68,7 @@
 import Data.String (IsString(..))
 import Data.Text (Text, pack)
 import Data.Word (Word)
+import Filesystem.Path.CurrentOS (FilePath, toText)
 import Numeric (showEFloat, showFFloat, showGFloat, showHex, showOct)
 import Prelude hiding ((.), id, FilePath)
 
@@ -185,5 +187,11 @@
 >>> repr (1,2)
 "(1,2)"
 -}
+
+{-| `Format` a `Filesystem.Path.CurrentOS` into `Text`
+-}
+fp :: Format r (FilePath -> r)
+fp = makeFormat (\fpath -> either id id (toText fpath))
+
 repr :: Show a => a -> Text
 repr = format w
diff --git a/src/Turtle/Pattern.hs b/src/Turtle/Pattern.hs
--- a/src/Turtle/Pattern.hs
+++ b/src/Turtle/Pattern.hs
@@ -92,6 +92,10 @@
     , fixed
     , sepBy
     , sepBy1
+
+    -- * High-efficiency primitives
+    , chars
+    , chars1
     ) where
 
 import Control.Applicative
@@ -450,7 +454,7 @@
 ["A"]
 -}
 prefix :: Pattern a -> Pattern a
-prefix p = p <* star anyChar
+prefix p = p <* chars
 
 {-| Use this to match the suffix of a string
 
@@ -460,7 +464,7 @@
 ["C"]
 -}
 suffix :: Pattern a -> Pattern a
-suffix p = star anyChar *> p
+suffix p = chars *> p
 
 {-| Use this to match the interior of a string
 
@@ -470,7 +474,7 @@
 ["B"]
 -}
 has :: Pattern a -> Pattern a
-has p = star anyChar *> p <* star anyChar
+has p = chars *> p <* chars
 
 {-| Parse 0 or more occurrences of the given character
 
@@ -478,6 +482,8 @@
 ["123"]
 >>> match (star anyChar) ""
 [""]
+
+    See also: `chars`
 -}
 star :: Pattern Char -> Pattern Text
 star p = fmap Text.pack (many p)
@@ -488,6 +494,8 @@
 ["123"]
 >>> match (plus anyChar) ""
 []
+
+    See also: `chars1`
 -}
 plus :: Pattern Char -> Pattern Text
 plus p = fmap Text.pack (some p)
@@ -612,3 +620,12 @@
 -}
 sepBy1 :: Pattern a -> Pattern b -> Pattern [a]
 p `sepBy1` sep = (:) <$> p <*> many (sep *> p) 
+
+-- | Like @star dot@ or @star anyChar@, except more efficient
+chars :: Pattern Text
+chars = Pattern (StateT (\txt ->
+    reverse (zip (Text.inits txt) (Text.tails txt)) ))
+
+-- | Like @plus dot@ or @plus anyChar@, except more efficient
+chars1 :: Pattern Text
+chars1 = Text.cons <$> dot <*> chars
diff --git a/src/Turtle/Prelude.hs b/src/Turtle/Prelude.hs
--- a/src/Turtle/Prelude.hs
+++ b/src/Turtle/Prelude.hs
@@ -378,7 +378,7 @@
 ls path = Shell (\(FoldM step begin done) -> do
     x0 <- begin
     let path' = Filesystem.encodeString path
-    canRead <- fmap readable (getPermissions path')
+    canRead <- fmap readable (getPermissions (deslash path'))
 #ifdef mingw32_HOST_OS
     reparse <- fmap reparsePoint (Win32.getFileAttributes path')
     if (canRead && not reparse)
@@ -412,6 +412,17 @@
             loop $! x0 )
         else done x0 )
 #endif
+
+{-| This is used to remove the trailing slash from a path, because
+    `getDirectoryPermissions` will fail if a path ends with a trailing slash
+-}
+deslash :: String -> String
+deslash []     = []
+deslash (c:cs) = c:go cs
+  where
+    go []     = []
+    go ['\\'] = []
+    go (c:cs) = c:go cs
 
 -- | Stream all recursive descendents of the given directory
 lstree :: FilePath -> Shell FilePath
diff --git a/src/Turtle/Shell.hs b/src/Turtle/Shell.hs
--- a/src/Turtle/Shell.hs
+++ b/src/Turtle/Shell.hs
@@ -47,7 +47,7 @@
 
 > -- For every shell `s`:
 > foldIO s (FoldM step begin done) = do
->     x  <- step
+>     x  <- begin
 >     x' <- foldIO s (FoldM step (return x) return)
 >     done x'
 
diff --git a/src/Turtle/Tutorial.hs b/src/Turtle/Tutorial.hs
--- a/src/Turtle/Tutorial.hs
+++ b/src/Turtle/Tutorial.hs
@@ -64,15 +64,15 @@
     -- * Loops
     -- $loops
 
-    -- * External commands
-    -- $external
-
     -- * Folds
     -- $folds
 
     -- * Input and output
     -- $io
 
+    -- * External commands
+    -- $external
+
     -- * Patterns
     -- $patterns
 
@@ -116,7 +116,9 @@
 -- code to generate a native executable which will have a much faster startup
 -- time and improved performance:
 --
--- > $ ghc -O2 example.hs  # -O2 turns on all optimizations
+-- > $ # `-O2` turns on all optimizations
+-- > $ # `-threaded` helps with piping shell output in and out of Haskell
+-- > $ ghc -O2 -threaded example.hs
 -- > $ ./example
 -- > Hello, world!
 --
@@ -1000,56 +1002,6 @@
 -- > FilePath "/tmp/ssh-vREYGbWGpiCa"
 -- > FilePath "/tmp/.ICE-unix"
 
--- $external
---
--- You can embed external shell commands as streams within your Haskell program.
---
--- For example, suppose that we want to use the system's built in @ls@ command.
--- We can just run:
---
--- > Prelude Turtle> stdout (inshell "ls" empty)
--- > .X11-unix
--- > .X0-lock
--- > pulse-PKdhtXMmr18n
--- > pulse-xHYcZ3zmN3Fv
--- > tracker-gabriel
--- > pulse-PYi1hSlWgNj2
--- > orbit-gabriel
--- > ssh-vREYGbWGpiCa
--- > .ICE-unix
---
--- This works because type of `inshell` is:
---
--- @
--- `inshell`
---     :: Text    -- Command line
---     -> Shell Text  -- Standard input to feed to program
---     -> Shell Text  -- Standard output produced by program
--- @
---
--- This means you can use `inshell` to embed arbitrary external utilities as
--- first class streams within your Haskell program:
---
--- > Turtle Prelude> stdout (inshell "awk '{ print $1 }'" "123 456")
--- > 123
---
--- You should also check out the `inproc` command, which is less powerful but
--- safer since it decreases the likelihood of code injection or malformed
--- commands:
---
--- @
--- `inproc`
---     :: Text        -- Program
---     -> [Text]      -- Arguments
---     -> Shell Text  -- Standard input to feed to program
---     -> Shell Text  -- Standard output produced by program
--- @
---
--- Using `inproc`, you would write:
---
--- > Turtle Prelude> stdout (inproc "awk" ["{ print $1 }"] "123 456")
--- > 123
-
 -- $folds
 --
 -- There are other ways you can consume a `Shell` stream.  For example, you can
@@ -1092,7 +1044,7 @@
 -- `stdout` :: Shell Text -> IO ()
 -- `stdout` s = sh (do
 --     txt <- s
---     liftIO (echo txt)
+--     liftIO (echo txt) )
 -- @
 --
 -- `stdout` outputs each `Text` value on its own line:
@@ -1144,6 +1096,56 @@
 -- ABC
 -- 42
 -- @
+
+-- $external
+--
+-- You can embed external shell commands as streams within your Haskell program.
+--
+-- For example, suppose that we want to use the system's built in @ls@ command.
+-- We can just run:
+--
+-- > Prelude Turtle> stdout (inshell "ls" empty)
+-- > .X11-unix
+-- > .X0-lock
+-- > pulse-PKdhtXMmr18n
+-- > pulse-xHYcZ3zmN3Fv
+-- > tracker-gabriel
+-- > pulse-PYi1hSlWgNj2
+-- > orbit-gabriel
+-- > ssh-vREYGbWGpiCa
+-- > .ICE-unix
+--
+-- This works because type of `inshell` is:
+--
+-- @
+-- `inshell`
+--     :: Text    -- Command line
+--     -> Shell Text  -- Standard input to feed to program
+--     -> Shell Text  -- Standard output produced by program
+-- @
+--
+-- This means you can use `inshell` to embed arbitrary external utilities as
+-- first class streams within your Haskell program:
+--
+-- > Turtle Prelude> stdout (inshell "awk '{ print $1 }'" "123 456")
+-- > 123
+--
+-- You should also check out the `inproc` command, which is less powerful but
+-- safer since it decreases the likelihood of code injection or malformed
+-- commands:
+--
+-- @
+-- `inproc`
+--     :: Text        -- Program
+--     -> [Text]      -- Arguments
+--     -> Shell Text  -- Standard input to feed to program
+--     -> Shell Text  -- Standard output produced by program
+-- @
+--
+-- Using `inproc`, you would write:
+--
+-- > Turtle Prelude> stdout (inproc "awk" ["{ print $1 }"] "123 456")
+-- > 123
 
 -- $patterns
 --
diff --git a/turtle.cabal b/turtle.cabal
--- a/turtle.cabal
+++ b/turtle.cabal
@@ -1,5 +1,5 @@
 Name: turtle
-Version: 1.0.1
+Version: 1.0.2
 Cabal-Version: >=1.10
 Build-Type: Simple
 License: BSD3
@@ -46,7 +46,7 @@
 Library
     HS-Source-Dirs: src
     Build-Depends:
-        base            >= 4       && < 5  ,
+        base            >= 4.5     && < 5  ,
         async           >= 2.0.0.0 && < 2.1,
         clock           >= 0.4.1.2 && < 0.5,
         directory                     < 1.3,
