diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright Ben Clifford (c) 2016
+Copyright Ben Clifford (c) 2016-2018
 
 All rights reserved.
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,11 +1,14 @@
 ACME Smuggler
 =============
 
-The () type has only one value, also called () with no
+The `()` type has only one value, also called `()` with no
 internal structure.
 
 Nevertheless, acme-smuggler allows you to smuggle
-arbitrary values into () and discover them later:
+arbitrary values into `()` and discover them later.
+
+And! `Void` has no values at all, but acme-smuggler lets you
+smuggle values into `Void`. Or into any other Haskell type.
 
 ```haskell
 > x = smuggle "hello"
diff --git a/acme-smuggler.cabal b/acme-smuggler.cabal
--- a/acme-smuggler.cabal
+++ b/acme-smuggler.cabal
@@ -1,13 +1,13 @@
 name:                acme-smuggler
-version:             0.1.0.1
-synopsis:            Smuggle arbitrary values in ()
+version:             1.1.1.0
+synopsis:            Smuggle arbitrary values in arbitrary types
 description:         Please see README.md
 homepage:            https://github.com/benclifford/acme-smuggler
 license:             BSD3
 license-file:        LICENSE
 author:              Ben Clifford <benc@hawaga.org.uk>
 maintainer:          Ben Clifford <benc@hawaga.org.uk>
-copyright:           2016 Ben Clifford
+copyright:           2016-2018 Ben Clifford
 category:            ACME
 build-type:          Simple
 extra-source-files:  README.md
diff --git a/src/Acme/Smuggler.hs b/src/Acme/Smuggler.hs
--- a/src/Acme/Smuggler.hs
+++ b/src/Acme/Smuggler.hs
@@ -1,25 +1,31 @@
 module Acme.Smuggler
-    ( inj, prj, smuggle, discover
+    ( inj, prj, smuggle, discover, mkId
     ) where
 
 import Data.Typeable (Typeable)
 import Data.Dynamic (toDyn, fromDynamic)
 import System.IO.Unsafe (unsafePerformIO)
-import Control.Exception (try, throw)
+import Control.Exception (try, throw, evaluate)
 
 -- | fancy name for smuggle
-inj :: Typeable t => t -> ()
+inj :: Typeable t => t -> a
 inj = smuggle
 
 -- | fancy name for discover
-prj :: Typeable t => () -> Maybe t
+prj :: Typeable t => a -> Maybe t
 prj = discover
 
-smuggle :: Typeable t => t -> ()
-smuggle v = unsafePerformIO $ throw (toDyn v)
+smuggle :: Typeable t => t -> a
+smuggle = throw . toDyn
 
-discover :: Typeable t => () -> Maybe t
-discover v = either (fromDynamic) (const Nothing)
-  $ unsafePerformIO
-  $ try
-  $ case v of () -> return ()
+discover :: Typeable t => a -> Maybe t
+discover = either (fromDynamic) (const Nothing)
+  . unsafePerformIO
+  . try
+  . evaluate
+
+-- | All functions of type (a -> a) are `id`. 
+-- This helper lets you create arbitrary `id` functions of
+-- type (a -> a) which smuggle through a supplied value
+mkId :: Typeable t => t -> (a -> a)
+mkId t = const (smuggle t)
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -1,14 +1,27 @@
 import Acme.Smuggler
+import Data.Typeable (Typeable)
+import Data.Void (Void)
 import Test.Hspec
 
 main :: IO ()
 main = hspec $ do
-  describe "prj . inj" $ do
-    it "conveys an integer" $ (prj . inj) (7 :: Integer) `shouldBe` Just (7 :: Integer)
+  describe "prj . inj via ()" $ do
+    it "conveys an integer" $ (prj . injUnit) (7 :: Integer) `shouldBe` Just (7 :: Integer)
     it "gives Nothing when going from an integer to a string" $
-      (prj . inj) (7 :: Integer) `shouldBe` (Nothing :: Maybe String)
+      (prj . injUnit) (7 :: Integer) `shouldBe` (Nothing :: Maybe String)
 
   describe "prj" $ do
     it "gives Nothing when projecting from a real ()" $
       (prj ()) `shouldBe` (Nothing :: Maybe Integer)
 
+
+  describe "prj . inj via Void" $ do
+    it "conveys an integer" $ (prj . injVoid) (7 :: Integer) `shouldBe` Just (7 :: Integer)
+    it "gives Nothing when going from an integer to a string" $
+      (prj . injVoid) (7 :: Integer) `shouldBe` (Nothing :: Maybe String)
+
+injUnit :: Typeable t => t -> ()
+injUnit = inj
+
+injVoid :: Typeable t => t -> Void
+injVoid = inj
