diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# gitson [![Hackage](https://img.shields.io/hackage/v/gitson.svg?style=flat)](https://hackage.haskell.org/package/gitson) [![Build Status](https://img.shields.io/travis/myfreeweb/gitson.svg?style=flat)](https://travis-ci.org/myfreeweb/gitson) [![Coverage Status](https://img.shields.io/coveralls/myfreeweb/gitson.svg?style=flat)](https://coveralls.io/r/myfreeweb/gitson) [![Apache License 2.0](https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg?style=flat)](https://www.tldrlegal.com/l/apache2)
+# gitson [![Hackage](https://img.shields.io/hackage/v/gitson.svg?style=flat)](https://hackage.haskell.org/package/gitson) [![Build Status](https://img.shields.io/travis/myfreeweb/gitson.svg?style=flat)](https://travis-ci.org/myfreeweb/gitson) [![Coverage Status](https://img.shields.io/coveralls/myfreeweb/gitson.svg?style=flat)](https://coveralls.io/r/myfreeweb/gitson) [![ISC License](https://img.shields.io/badge/license-ISC-red.svg?style=flat)](https://tldrlegal.com/license/-isc-license)
 
 A simple document store library for Git + JSON, based on [Aeson].
 Uses command line git, at least for now.
@@ -104,16 +104,5 @@
 
 ## License
 
-Copyright 2014 Greg V <floatboth@me.com>
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
+Copyright 2014-2015 Greg V <greg@unrelenting.technology>
+Available under the ISC license, see the `COPYING` file
diff --git a/gitson.cabal b/gitson.cabal
--- a/gitson.cabal
+++ b/gitson.cabal
@@ -1,5 +1,5 @@
 name:            gitson
-version:         0.5.0
+version:         0.5.1
 synopsis:        A document store library for Git + JSON.
 description:     A simple document store library for Git + JSON, based on Aeson. Uses command line git. Transactions use flock, so it's safe even across completely separate programs!
 category:        Database, JSON, Git
@@ -7,14 +7,14 @@
 author:          Greg V
 copyright:       2014-2015 Greg V <greg@unrelenting.technology>
 maintainer:      greg@unrelenting.technology
-license:         Apache-2.0
+license:         OtherLicense
 license-file:    COPYING
 build-type:      Simple
 cabal-version:   >= 1.18
 extra-source-files:
     README.md
 tested-with:
-    GHC == 7.8.2
+    GHC == 7.8.3
 
 source-repository head
     type: git
@@ -45,8 +45,8 @@
 test-suite examples
     build-depends:
         base >= 4.0.0.0 && < 5
-      , Glob == 0.*
-      , doctest >= 0.8
+      , Glob
+      , doctest
     default-language: Haskell2010
     ghc-options: -threaded -Wall -Werror
     hs-source-dirs: test-suite
@@ -61,9 +61,7 @@
       , process
       , directory
       , aeson
-      , hspec == 1.*
-        , HUnit
-        , QuickCheck
+      , hspec
     default-language: Haskell2010
     ghc-options: -threaded -Wall -Werror -fhpc
     hs-source-dirs: test-suite
@@ -80,9 +78,7 @@
       , random
       , gitson
       , aeson
-      , criterion == 0.6.*
-        , hastache < 0.6
-        , statistics < 0.11
+      , criterion
     default-language: Haskell2010
     hs-source-dirs: benchmark
     main-is: Bench.hs
diff --git a/library/Gitson.hs b/library/Gitson.hs
--- a/library/Gitson.hs
+++ b/library/Gitson.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE Safe, FlexibleContexts #-}
+{-# LANGUAGE Safe, FlexibleContexts, UnicodeSyntax #-}
 
 -- | Gitson is a simple document store library for Git + JSON.
 module Gitson (
@@ -21,13 +21,14 @@
 
 import           System.Directory
 import           System.Lock.FLock
-import           Control.Applicative ((<$>))
+import           Control.Applicative
 import           Control.Exception (try, IOException)
 import           Control.Error.Util (hush)
 import           Control.Monad.Trans.Writer
 import           Control.Monad.Trans.Control
 import           Control.Monad.IO.Class
-import           Data.Maybe (fromMaybe, catMaybes)
+import           Control.Monad (liftM)
+import           Data.Maybe (fromMaybe, mapMaybe)
 import           Data.List (find, isSuffixOf)
 import           Text.Printf (printf)
 import qualified Data.ByteString.Lazy as BL
@@ -39,133 +40,126 @@
 
 type IdAndName = (Int, String)
 type FileName = String
-type Finder = ([(IdAndName, FileName)] -> Maybe (IdAndName, FileName))
+type Finder = [(IdAndName, FileName)] → Maybe (IdAndName, FileName)
 
-splitFindDocument :: (MonadIO i) => FilePath -> Finder -> i (Maybe (IdAndName, FileName))
-splitFindDocument collection finder = listDocumentKeys collection >>=
-  return . finder . catMaybes . map (\x -> intoFunctor (maybeReadIntString x) x)
+splitFindDocument ∷ (MonadIO i, Functor i) ⇒ FilePath → Finder → i (Maybe (IdAndName, FileName))
+splitFindDocument collection finder = 
+  finder . mapMaybe (\x → intoFunctor (maybeReadIntString x) x) <$> listDocumentKeys collection
 
-documentFullKey :: (MonadIO i) => FilePath -> Finder -> i (Maybe FileName)
-documentFullKey collection finder = splitFindDocument collection finder >>= return . (snd <$>)
+documentFullKey ∷ (MonadIO i, Functor i) ⇒ FilePath → Finder → i (Maybe FileName)
+documentFullKey collection finder = (snd <$>) <$> splitFindDocument collection finder
 
-findById :: Int -> Finder
+findById ∷ Int → Finder
 findById i = find $ (== i) . fst . fst
 
-findByName :: String -> Finder
-findByName n = find $ (isSuffixOf n) . snd . fst
+findByName ∷ String → Finder
+findByName n = find $ isSuffixOf n . snd . fst
 
 -- | Creates a git repository under a given path.
-createRepo :: FilePath -> IO ()
+createRepo ∷ FilePath → IO ()
 createRepo path = do
   createDirectoryIfMissing True path
   insideDirectory path $ shell "git" ["init"]
 
 -- | Executes a blocking transaction on a repository, committing the results to git.
-transaction :: (MonadIO i, MonadBaseControl IO i) => FilePath -> TransactionWriter i () -> i ()
+transaction ∷ (MonadIO i, Functor i, MonadBaseControl IO i) ⇒ FilePath → TransactionWriter i () → i ()
 transaction repoPath action =
   insideDirectory repoPath $ do
     liftIO $ writeFile lockPath ""
     withLock lockPath Exclusive Block $ do
-      writeActions <- execWriterT action
+      writeActions ← execWriterT action
       shell "git" ["stash"] -- it's totally ok to do this without changes
       liftIO $ sequence_ writeActions
       shell "git" ["add", "--all"]
       shell "git" ["commit", "-m", "Gitson transaction"]
       shell "git" ["stash", "pop"]
 
-combineKey :: IdAndName -> FileName
-combineKey (n, s) = zeroPad n ++ "-" ++ s
-  where zeroPad :: Int -> String
-        zeroPad x = printf "%06d" x
+combineKey ∷ IdAndName → FileName
+combineKey (n, s) = printf "%06d-%s" n s
 
-writeDocument :: ToJSON a => FilePath -> FileName -> a -> IO ()
+writeDocument ∷ ToJSON a ⇒ FilePath → FileName → a → IO ()
 writeDocument collection key content = BL.writeFile (documentPath collection key) (encode content)
 
 -- | Adds a write action to a transaction.
-saveDocument :: (MonadIO i, ToJSON a) => FilePath -> FileName -> a -> TransactionWriter i ()
-saveDocument collection key content = do
+saveDocument ∷ (MonadIO i, Functor i, ToJSON a) ⇒ FilePath → FileName → a → TransactionWriter i ()
+saveDocument collection key content =
   tell [createDirectoryIfMissing True collection,
         writeDocument collection key content]
 
 -- | Adds a write action to a transaction.
 -- The key will start with a numeric id, incremented from the last id in the collection.
-saveNextDocument :: (MonadIO i, ToJSON a) => FilePath -> FileName -> a -> TransactionWriter i ()
-saveNextDocument collection key content = do
+saveNextDocument ∷ (MonadIO i, Functor i, ToJSON a) ⇒ FilePath → FileName → a → TransactionWriter i ()
+saveNextDocument collection key content =
   tell [createDirectoryIfMissing True collection,
         listDocumentKeys collection >>=
         return . nextKeyId >>=
-        \nextId -> writeDocument collection (combineKey (nextId, key)) content]
+        \nextId → writeDocument collection (combineKey (nextId, key)) content]
 
 -- | Adds a write action to a transaction.
 -- Will update the document with the given numeric id.
-saveDocumentById :: (MonadIO i, ToJSON a) => FilePath -> Int -> a -> TransactionWriter i ()
-saveDocumentById collection i content = do
+saveDocumentById ∷ (MonadIO i, Functor i, ToJSON a) ⇒ FilePath → Int → a → TransactionWriter i ()
+saveDocumentById collection i content =
   tell [documentFullKey collection (findById i) >>=
-        \k -> case k of
-          Just key -> writeDocument collection key content
-          Nothing -> return ()]
+        \k → case k of
+          Just key → writeDocument collection key content
+          Nothing → return ()]
 
 -- | Adds a write action to a transaction.
 -- Will update the document with the given numeric id.
-saveDocumentByName :: (MonadIO i, ToJSON a) => FilePath -> String -> a -> TransactionWriter i ()
-saveDocumentByName collection n content = do
+saveDocumentByName ∷ (MonadIO i, Functor i, ToJSON a) ⇒ FilePath → String → a → TransactionWriter i ()
+saveDocumentByName collection n content =
   tell [documentFullKey collection (findByName n) >>=
-        \k -> case k of
-          Just key -> writeDocument collection key content
-          Nothing -> return ()]
+        \k → case k of
+          Just key → writeDocument collection key content
+          Nothing → return ()]
 
 -- | Lists collections in the current repository.
-listCollections :: (MonadIO i) => i [FilePath]
+listCollections ∷ (MonadIO i, Functor i) ⇒ i [FilePath]
 listCollections = liftIO $ do
-  contents <- try (getDirectoryContents =<< getCurrentDirectory) :: IO (Either IOException [FilePath])
+  contents ← try (getDirectoryContents =<< getCurrentDirectory) ∷ IO (Either IOException [FilePath])
   filterDirs $ fromMaybe [] $ hush contents
 
 -- | Lists document keys in a collection.
-listDocumentKeys :: (MonadIO i) => FilePath -> i [FileName]
+listDocumentKeys ∷ (MonadIO i, Functor i) ⇒ FilePath → i [FileName]
 listDocumentKeys collection = liftIO $ do
-  contents <- try (getDirectoryContents collection) :: IO (Either IOException [String])
-  return $ filterFilenamesAsKeys $ fromMaybe [] $ hush contents
+  contents ← try (getDirectoryContents collection) ∷ IO (Either IOException [String])
+  return . filterFilenamesAsKeys . fromMaybe [] $ hush contents
 
 -- | Lists entries in a collection.
-listEntries :: (MonadIO i, FromJSON a) => FilePath -> i [a]
+listEntries ∷ (MonadIO i, Functor i, FromJSON a) ⇒ FilePath → i [a]
 listEntries collection = liftIO $ do
-  ks <- listDocumentKeys collection
-  maybes <- mapM (readDocument collection) ks
-  return $ fromMaybe [] $ sequence maybes
+  maybes ← mapM (readDocument collection) =<< listDocumentKeys collection
+  return . fromMaybe [] $ sequence maybes
 
 -- | Reads a document from a collection by key.
-readDocument :: (MonadIO i, FromJSON a) => FilePath -> FileName -> i (Maybe a)
+readDocument ∷ (MonadIO i, Functor i, FromJSON a) ⇒ FilePath → FileName → i (Maybe a)
 readDocument collection key = liftIO $ do
-  jsonString <- try (BL.readFile $ documentPath collection key) :: IO (Either IOException BL.ByteString)
+  jsonString ← try (BL.readFile $ documentPath collection key) ∷ IO (Either IOException BL.ByteString)
   return $ decode =<< hush jsonString
 
-readDocument' :: (MonadIO i, FromJSON a) => FilePath -> Maybe FileName -> i (Maybe a)
+readDocument' ∷ (MonadIO i, Functor i, FromJSON a) ⇒ FilePath → Maybe FileName → i (Maybe a)
 readDocument' collection key = liftIO $ case key of
-  Just key -> readDocument collection key
-  Nothing -> return Nothing
+  Just key → readDocument collection key
+  Nothing → return Nothing
 
 -- | Reads a document from a collection by numeric id (for example, key "00001-hello" has id 1).
-readDocumentById :: (MonadIO i, FromJSON a) => FilePath -> Int -> i (Maybe a)
+readDocumentById ∷ (MonadIO i, Functor i, FromJSON a) ⇒ FilePath → Int → i (Maybe a)
 readDocumentById collection i =
-  documentFullKey collection (findById i) >>=
-  readDocument' collection
+  readDocument' collection =<< documentFullKey collection (findById i)
 
 -- | Reads a document from a collection by name (for example, key "00001-hello" has name "hello").
-readDocumentByName :: (MonadIO i, FromJSON a) => FilePath -> String -> i (Maybe a)
+readDocumentByName ∷ (MonadIO i, Functor i, FromJSON a) ⇒ FilePath → String → i (Maybe a)
 readDocumentByName collection n =
-  documentFullKey collection (findByName n) >>=
-  readDocument' collection
+  readDocument' collection =<< documentFullKey collection (findByName n)
 
 -- | Returns a document's id by name (for example, "hello" will return 23 when key "00023-hello" exists).
 -- Does not read the document!
-documentIdFromName :: (MonadIO i) => FilePath -> String -> i (Maybe Int)
+documentIdFromName ∷ (MonadIO i, Functor i) ⇒ FilePath → String → i (Maybe Int)
 documentIdFromName collection n =
-  splitFindDocument collection (findByName n) >>=
-  return . (fst <$> fst <$>)
+  (fst <$> fst <$>) <$> splitFindDocument collection (findByName n)
 
 -- | Returns a document's name by id (for example, 23 will return "hello" when key "00023-hello" exists).
 -- Does not read the document!
-documentNameFromId :: (MonadIO i) => FilePath -> Int -> i (Maybe String)
+documentNameFromId ∷ (MonadIO i, Functor i) ⇒ FilePath → Int → i (Maybe String)
 documentNameFromId collection i =
-  splitFindDocument collection (findById i) >>=
-  return . (drop 1 . snd <$> fst <$>)
+  (drop 1 . snd <$> fst <$>) <$> splitFindDocument collection (findById i)
diff --git a/library/Gitson/Util.hs b/library/Gitson/Util.hs
--- a/library/Gitson/Util.hs
+++ b/library/Gitson/Util.hs
@@ -36,13 +36,13 @@
 
 -- | Filters a list of file paths, leaving only paths to existing non-hidden directories.
 filterDirs :: [FilePath] -> IO [FilePath]
-filterDirs = (filterM doesDirectoryExist) . filter (not . isPrefixOf ".")
+filterDirs = filterM doesDirectoryExist . filter (not . isPrefixOf ".")
 
 -- | Returns an IO action that switches the current directory to a given path,
 -- executes the given IO action and switches the current directory back.
 insideDirectory :: (MonadIO i) => FilePath -> i a -> i a
 insideDirectory path action = do
-  prevPath <- liftIO $ getCurrentDirectory
+  prevPath <- liftIO getCurrentDirectory
   liftIO $ setCurrentDirectory path
   result <- action
   liftIO $ setCurrentDirectory prevPath
@@ -93,7 +93,7 @@
 -- >>> nextKeyId ["1-hell0-w0rld-123456.json", "002-my-second-post.json"]
 -- 3
 nextKeyId :: [String] -> Int
-nextKeyId = (+1) . maxOrZero . catMaybes . map maybeReadInt
+nextKeyId = (+1) . maxOrZero . mapMaybe maybeReadInt
   where maybeReadInt x = fst <$> maybeReadIntString x
         maxOrZero [] = 0
         maxOrZero xs = maximum xs
diff --git a/test-suite/GitsonSpec.hs b/test-suite/GitsonSpec.hs
--- a/test-suite/GitsonSpec.hs
+++ b/test-suite/GitsonSpec.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TemplateHaskell, UnicodeSyntax #-}
 
 module GitsonSpec (spec) where
 
@@ -12,10 +12,12 @@
 import           Gitson
 import           Gitson.Util (insideDirectory, lastCommitText)
 
-data Thing = Thing { val :: Int } deriving (Eq, Show, Ord)
+{-# ANN module ("HLint: ignore Redundant do" :: String) #-}
+
+data Thing = Thing { val ∷ Int } deriving (Eq, Show, Ord)
 $(deriveJSON defaultOptions ''Thing)
 
-spec :: Spec
+spec ∷ Spec
 spec = before setup $ after cleanup $ do
   context "transaction" $ do
     describe "saveDocument" $ do
@@ -23,14 +25,14 @@
         transaction "tmp/repo" $ do
           saveDocument "things" "first-thing" Thing {val = 1}
           saveDocument "things" "second-thing" Thing {val = 2}
-          liftIO $ (readFile "things/first-thing.json") `shouldThrow` anyIOException
-          liftIO $ (readFile "things/second-thing.json") `shouldThrow` anyIOException
+          liftIO $ readFile "things/first-thing.json" `shouldThrow` anyIOException
+          liftIO $ readFile "things/second-thing.json" `shouldThrow` anyIOException
         insideDirectory "tmp/repo" $ do
-          first <- readFile "things/first-thing.json"
+          first ← readFile "things/first-thing.json"
           first `shouldBe` "{\n  \"val\": 1\n}"
-          second <- readFile "things/second-thing.json"
+          second ← readFile "things/second-thing.json"
           second `shouldBe` "{\n  \"val\": 2\n}"
-          commitMsg <- lastCommitText
+          commitMsg ← lastCommitText
           commitMsg `shouldBe` "Gitson transaction"
 
     describe "saveNextDocument" $ do
@@ -39,108 +41,108 @@
           saveNextDocument "things" "hello" Thing {val = 1}
           saveNextDocument "things" "world" Thing {val = 2}
         insideDirectory "tmp/repo" $ do
-          first <- readFile "things/000001-hello.json"
+          first ← readFile "things/000001-hello.json"
           first `shouldBe` "{\n  \"val\": 1\n}"
-          second <- readFile "things/000002-world.json"
+          second ← readFile "things/000002-world.json"
           second `shouldBe` "{\n  \"val\": 2\n}"
 
     describe "saveDocumentById" $ do
       it "updates an entry by specified id" $ do
         createDirectoryIfMissing True "tmp/repo/things"
-        _ <- liftIO $ writeFile "tmp/repo/things/000004-second-thing.json" "{\"val\":1}"
+        _ ← liftIO $ writeFile "tmp/repo/things/000004-second-thing.json" "{\"val\":1}"
         transaction "tmp/repo" $ do
           saveDocumentById "things" 4 Thing {val = 2}
         insideDirectory "tmp/repo" $ do
-          second <- readFile "things/000004-second-thing.json"
+          second ← readFile "things/000004-second-thing.json"
           second `shouldBe` "{\n  \"val\": 2\n}"
 
     describe "saveDocumentByName" $ do
       it "updates an entry by specified name" $ do
         createDirectoryIfMissing True "tmp/repo/things"
-        _ <- liftIO $ writeFile "tmp/repo/things/000004-second-thing.json" "{\"val\":1}"
+        _ ← liftIO $ writeFile "tmp/repo/things/000004-second-thing.json" "{\"val\":1}"
         transaction "tmp/repo" $ do
           saveDocumentByName "things" "second-thing" Thing {val = 2}
         insideDirectory "tmp/repo" $ do
-          second <- readFile "things/000004-second-thing.json"
+          second ← readFile "things/000004-second-thing.json"
           second `shouldBe` "{\n  \"val\": 2\n}"
 
   describe "readDocument" $ do
     it "returns Just the document when reading an document by key" $ do
       createDirectoryIfMissing True "tmp/repo/things"
-      _ <- writeFile "tmp/repo/things/second-thing.json" "{\"val\":2}"
-      content <- readDocument "tmp/repo/things" "second-thing" :: IO (Maybe Thing)
+      _ ← writeFile "tmp/repo/things/second-thing.json" "{\"val\":2}"
+      content ← readDocument "tmp/repo/things" "second-thing" ∷ IO (Maybe Thing)
       content `shouldBe` Just Thing {val = 2}
 
     it "returns Nothing when reading by a nonexistent key" $ do
-      content <- readDocument "tmp/repo/things" "totally-not-a-thing" :: IO (Maybe Thing)
+      content ← readDocument "tmp/repo/things" "totally-not-a-thing" ∷ IO (Maybe Thing)
       content `shouldBe` Nothing
 
   describe "readDocumentById" $ do
     it "returns Just the document when reading an document by id" $ do
       createDirectoryIfMissing True "tmp/repo/things"
-      _ <- writeFile "tmp/repo/things/000004-second-thing.json" "{\"val\":1}"
-      content <- readDocumentById "tmp/repo/things" 4 :: IO (Maybe Thing)
+      _ ← writeFile "tmp/repo/things/000004-second-thing.json" "{\"val\":1}"
+      content ← readDocumentById "tmp/repo/things" 4 ∷ IO (Maybe Thing)
       content `shouldBe` Just Thing {val = 1}
 
     it "returns Nothing when reading by a nonexistent id" $ do
-      content <- readDocumentById "tmp/repo/things" 1 :: IO (Maybe Thing)
+      content ← readDocumentById "tmp/repo/things" 1 ∷ IO (Maybe Thing)
       content `shouldBe` Nothing
 
   describe "readDocumentByName" $ do
     it "returns Just the document when reading an document by name" $ do
       createDirectoryIfMissing True "tmp/repo/things"
-      _ <- writeFile "tmp/repo/things/000098-second-thing.json" "{\"val\":1}"
-      content <- readDocumentByName "tmp/repo/things" "second-thing" :: IO (Maybe Thing)
+      _ ← writeFile "tmp/repo/things/000098-second-thing.json" "{\"val\":1}"
+      content ← readDocumentByName "tmp/repo/things" "second-thing" ∷ IO (Maybe Thing)
       content `shouldBe` Just Thing {val = 1}
 
     it "returns Nothing when reading by a nonexistent name" $ do
-      content <- readDocumentByName "tmp/repo/things" "yolo" :: IO (Maybe Thing)
+      content ← readDocumentByName "tmp/repo/things" "yolo" ∷ IO (Maybe Thing)
       content `shouldBe` Nothing
 
   describe "documentIdFromName" $ do
     it "returns Just the document id from the document's name" $ do
       createDirectoryIfMissing True "tmp/repo/things"
-      _ <- writeFile "tmp/repo/things/000098-some-thing.json" "THIS SHOULD NOT BE READ"
-      i <- documentIdFromName "tmp/repo/things" "some-thing"
+      _ ← writeFile "tmp/repo/things/000098-some-thing.json" "THIS SHOULD NOT BE READ"
+      i ← documentIdFromName "tmp/repo/things" "some-thing"
       i `shouldBe` Just 98
 
     it "returns Nothing when run with a nonexistent name" $ do
-      i <- documentIdFromName "tmp/repo/things" "yolo"
+      i ← documentIdFromName "tmp/repo/things" "yolo"
       i `shouldBe` Nothing
 
   describe "documentNameFromId" $ do
     it "returns Just the document name from the document's id" $ do
       createDirectoryIfMissing True "tmp/repo/things"
-      _ <- writeFile "tmp/repo/things/000098-some-thing.json" "THIS SHOULD NOT BE READ"
-      i <- documentNameFromId "tmp/repo/things" 98
+      _ ← writeFile "tmp/repo/things/000098-some-thing.json" "THIS SHOULD NOT BE READ"
+      i ← documentNameFromId "tmp/repo/things" 98
       i `shouldBe` Just "some-thing"
 
     it "returns Nothing when run with a nonexistent id" $ do
-      i <- documentNameFromId "tmp/repo/things" 123
+      i ← documentNameFromId "tmp/repo/things" 123
       i `shouldBe` Nothing
 
   describe "listDocumentKeys" $ do
     it "returns a list of document keys when listing a collection" $ do
       createDirectoryIfMissing True "tmp/repo/things"
-      _ <- writeFile "tmp/repo/things/first-thing.json" "{}"
-      _ <- writeFile "tmp/repo/things/second-thing.json" "{}"
-      list <- listDocumentKeys "tmp/repo/things"
+      _ ← writeFile "tmp/repo/things/first-thing.json" "{}"
+      _ ← writeFile "tmp/repo/things/second-thing.json" "{}"
+      list ← listDocumentKeys "tmp/repo/things"
       sort list `shouldBe` ["first-thing", "second-thing"]
 
     it "returns an empty when listing a nonexistent collection" $ do
-      list <- listDocumentKeys "nonsense"
+      list ← listDocumentKeys "nonsense"
       list `shouldBe` []
 
   describe "listEntries" $ do
     it "returns a list of entries when listing a collection" $ do
       createDirectoryIfMissing True "tmp/repo/things"
-      _ <- writeFile "tmp/repo/things/first-thing.json" "{\"val\":1}"
-      _ <- writeFile "tmp/repo/things/second-thing.json" "{\"val\":2}"
-      list <- listEntries "tmp/repo/things" :: IO [Thing]
+      _ ← writeFile "tmp/repo/things/first-thing.json" "{\"val\":1}"
+      _ ← writeFile "tmp/repo/things/second-thing.json" "{\"val\":2}"
+      list ← listEntries "tmp/repo/things" ∷ IO [Thing]
       sort list `shouldBe` [Thing {val = 1}, Thing {val = 2}]
 
     it "returns an empty list when listing a nonexistent collection" $ do
-      list <- listEntries "nonsense" :: IO [Thing]
+      list ← listEntries "nonsense" ∷ IO [Thing]
       list `shouldBe` []
 
   describe "listCollections" $ do
@@ -148,17 +150,17 @@
       createDirectoryIfMissing True "tmp/repo/bits"
       createDirectoryIfMissing True "tmp/repo/pieces"
       insideDirectory "tmp/repo" $ do
-        list <- listCollections
+        list ← listCollections
         sort list `shouldBe` ["bits", "pieces"]
 
     it "returns an empty list when listing an empty repo" $ do
       createDirectoryIfMissing True "tmp/repo"
       insideDirectory "tmp/repo" $ do
-        list <- listCollections
+        list ← listCollections
         sort list `shouldBe` []
 
-setup :: IO ()
+setup ∷ IO ()
 setup = createRepo "tmp/repo"
 
-cleanup :: IO ()
-cleanup = void (try (removeDirectoryRecursive "tmp/repo") :: IO (Either IOException ()))
+cleanup ∷ ActionWith ()
+cleanup () = void (try (removeDirectoryRecursive "tmp/repo") ∷ IO (Either IOException ()))
