diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,8 +1,12 @@
 # Revision history for describe
 
+## 0.1.2.0 -- 2019-09-08
+
+* Fixed Monad instance.
+
 ## 0.1.1.0 -- 2019-09-05
 
-* Added Monad instance for Descriptor
+* Added Monad instance for Descriptor.
 
 ## 0.1.0.0 -- 2019-06-03
 
diff --git a/describe.cabal b/describe.cabal
--- a/describe.cabal
+++ b/describe.cabal
@@ -3,7 +3,7 @@
 --   For further documentation, see http://haskell.org/cabal/users-guide/
 
 name:                describe
-version:             0.1.1.0
+version:             0.1.2.0
 synopsis:            Combinators for describing binary data structures
 description:         Combinators for describing binary data structures, which eliminate the boilerplate of having to write isomorphic Get and Put instances. Please see the Github page for examples.
 homepage:            https://github.com/riugabachi/describe
diff --git a/src/Data/Serialize/Descriptor.hs b/src/Data/Serialize/Descriptor.hs
--- a/src/Data/Serialize/Descriptor.hs
+++ b/src/Data/Serialize/Descriptor.hs
@@ -12,7 +12,7 @@
 
 -- | @Descriptor s a@ is an applicative functor that describes the binary structure for a structure 's' while deserializing value 'a'.
 newtype Descriptor s a = Descriptor {
-    unwrapDescriptor :: (Get a, s -> Put)
+    unwrapDescriptor :: (Get a, s -> PutM a)
 }
 
 -- | @unwrapGet desc@ takes a 'Descriptor' and returns only the internal 'Get' monad.
@@ -21,25 +21,25 @@
 
 -- | @unwrapPut s desc@ takes the structure being described and a 'Descriptor' for it, and returns the internal 'Put' monad.
 unwrapPut :: s -> Descriptor s a -> PutM ()
-unwrapPut s = ($ s) . snd . unwrapDescriptor
+unwrapPut s = ($ s) . snd . unwrapDescriptor . (>> pure ())
 
 -- | Convenience function for @runPut . unwrapPut s@
 serialize :: s -> Descriptor s a -> ByteString
-serialize s = snd . runPutM . unwrapPut s
+serialize s = snd . runPutM . unwrapPut s . (>> pure ())
 
 -- | Convenience function for @flip runGet bs . unwrapGet@
 deserialize :: ByteString -> Descriptor s s -> Either String s
 deserialize bs = flip runGet bs . unwrapGet
 
 instance Functor (Descriptor s) where
-  fmap f (Descriptor (g, p)) = Descriptor (f <$> g, p)
+  fmap f (Descriptor (g, p)) = Descriptor (f <$> g, (f <$>) . p)
 
 instance Applicative (Descriptor s) where
-  pure a = Descriptor (pure a, \_ -> pure ())
+  pure a = Descriptor (pure a, \_ -> pure a)
   (Descriptor (f, p)) <*> (Descriptor (g, p')) =
-    Descriptor (f <*> g, \s' -> p s' >> p' s')
+    Descriptor (f <*> g, \s' -> p s' <*> p' s')
 
 instance Monad (Descriptor s) where
   (Descriptor (g, p)) >>= f =
-    Descriptor (g >>= fst . unwrapDescriptor . f, \s -> (p s <>) . ($ s) . snd . unwrapDescriptor . f $ undefined)
+    Descriptor (g >>= fst . unwrapDescriptor . f, \s -> p s >>= ($ s) . snd . unwrapDescriptor . f)
 
diff --git a/src/Data/Serialize/Descriptor/BE.hs b/src/Data/Serialize/Descriptor/BE.hs
--- a/src/Data/Serialize/Descriptor/BE.hs
+++ b/src/Data/Serialize/Descriptor/BE.hs
@@ -17,31 +17,31 @@
 import Data.Serialize.Descriptor
 
 w8 :: (a -> Word8) -> Descriptor a Word8
-w8 f = Descriptor (getWord8, \s' -> putWord8 (f s'))
+w8 f = Descriptor (getWord8, \s' -> putWord8 (f s') >> pure (f s'))
 
 w16 :: (a -> Word16) -> Descriptor a Word16
-w16 f = Descriptor (getWord16be, \s' -> putWord16be (f s'))
+w16 f = Descriptor (getWord16be, \s' -> putWord16be (f s') >> pure (f s'))
 
 w32 :: (a -> Word32) -> Descriptor a Word32
-w32 f = Descriptor (getWord32be, \s' -> putWord32be (f s'))
+w32 f = Descriptor (getWord32be, \s' -> putWord32be (f s') >> pure (f s'))
 
 w64 :: (a -> Word64) -> Descriptor a Word64
-w64 f = Descriptor (getWord64be, \s' -> putWord64be (f s'))
+w64 f = Descriptor (getWord64be, \s' -> putWord64be (f s') >> pure (f s'))
 
 i8 :: (a -> Int8) -> Descriptor a Int8
-i8 f = Descriptor (getInt8, \s' -> putInt8 (f s'))
+i8 f = Descriptor (getInt8, \s' -> putInt8 (f s') >> pure (f s'))
 
 i16 :: (a -> Int16) -> Descriptor a Int16
-i16 f = Descriptor (getInt16be, \s' -> putInt16be (f s'))
+i16 f = Descriptor (getInt16be, \s' -> putInt16be (f s') >> pure (f s'))
 
 i32 :: (a -> Int32) -> Descriptor a Int32
-i32 f = Descriptor (getInt32be, \s' -> putInt32be (f s'))
+i32 f = Descriptor (getInt32be, \s' -> putInt32be (f s') >> pure (f s'))
 
 i64 :: (a -> Int64) -> Descriptor a Int64
-i64 f = Descriptor (getInt64be, \s' -> putInt64be (f s'))
+i64 f = Descriptor (getInt64be, \s' -> putInt64be (f s') >> pure (f s'))
 
 f32 :: (a -> Float) -> Descriptor a Float
-f32 f = Descriptor (getFloat32be, \s' -> putFloat32be (f s'))
+f32 f = Descriptor (getFloat32be, \s' -> putFloat32be (f s') >> pure (f s'))
 
 f64 :: (a -> Double) -> Descriptor a Double
-f64 f = Descriptor (getFloat64be, \s' -> putFloat64be (f s'))
+f64 f = Descriptor (getFloat64be, \s' -> putFloat64be (f s') >> pure (f s'))
diff --git a/src/Data/Serialize/Descriptor/LE.hs b/src/Data/Serialize/Descriptor/LE.hs
--- a/src/Data/Serialize/Descriptor/LE.hs
+++ b/src/Data/Serialize/Descriptor/LE.hs
@@ -18,31 +18,31 @@
 import Data.Serialize.Descriptor
 
 w8 :: (a -> Word8) -> Descriptor a Word8
-w8 f = Descriptor (getWord8, \s' -> putWord8 (f s'))
+w8 f = Descriptor (getWord8, \s' -> putWord8 (f s') >> pure (f s'))
 
 w16 :: (a -> Word16) -> Descriptor a Word16
-w16 f = Descriptor (getWord16le, \s' -> putWord16le (f s'))
+w16 f = Descriptor (getWord16le, \s' -> putWord16le (f s') >> pure (f s'))
 
 w32 :: (a -> Word32) -> Descriptor a Word32
-w32 f = Descriptor (getWord32le, \s' -> putWord32le (f s'))
+w32 f = Descriptor (getWord32le, \s' -> putWord32le (f s') >> pure (f s'))
 
 w64 :: (a -> Word64) -> Descriptor a Word64
-w64 f = Descriptor (getWord64le, \s' -> putWord64le (f s'))
+w64 f = Descriptor (getWord64le, \s' -> putWord64le (f s') >> pure (f s'))
 
 i8 :: (a -> Int8) -> Descriptor a Int8
-i8 f = Descriptor (getInt8, \s' -> putInt8 (f s'))
+i8 f = Descriptor (getInt8, \s' -> putInt8 (f s') >> pure (f s'))
 
 i16 :: (a -> Int16) -> Descriptor a Int16
-i16 f = Descriptor (getInt16le, \s' -> putInt16le (f s'))
+i16 f = Descriptor (getInt16le, \s' -> putInt16le (f s') >> pure (f s'))
 
 i32 :: (a -> Int32) -> Descriptor a Int32
-i32 f = Descriptor (getInt32le, \s' -> putInt32le (f s'))
+i32 f = Descriptor (getInt32le, \s' -> putInt32le (f s') >> pure (f s'))
 
 i64 :: (a -> Int64) -> Descriptor a Int64
-i64 f = Descriptor (getInt64le, \s' -> putInt64le (f s'))
+i64 f = Descriptor (getInt64le, \s' -> putInt64le (f s') >> pure (f s'))
 
 f32 :: (a -> Float) -> Descriptor a Float
-f32 f = Descriptor (getFloat32le, \s' -> putFloat32le (f s'))
+f32 f = Descriptor (getFloat32le, \s' -> putFloat32le (f s') >> pure (f s'))
 
 f64 :: (a -> Double) -> Descriptor a Double
-f64 f = Descriptor (getFloat64le, \s' -> putFloat64le (f s'))
+f64 f = Descriptor (getFloat64le, \s' -> putFloat64le (f s') >> pure (f s'))
