diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,16 @@
 # Changelog
 
+## 0.36
+
+* File output now needs a third component, specifying if the file is
+  served as 'attachment' or not. If so, this will make most browsers
+  download the file instead of displaying it. This is a breaking
+  change. You can add a third element `False` to the return value to
+  get the old behaviour.
+
+* Re-exported XML serializable types from `rest-types` no longer have
+  `regular` `PF` instances since they are now using GHC Generics.
+
 #### 0.35.1
 
 * Remove unneeded constraint from `domainReason`.
diff --git a/rest-core.cabal b/rest-core.cabal
--- a/rest-core.cabal
+++ b/rest-core.cabal
@@ -1,5 +1,5 @@
 name:                rest-core
-version:             0.35.1
+version:             0.36
 description:         Rest API library.
 synopsis:            Rest API library.
 maintainer:          code@silk.co
@@ -55,9 +55,8 @@
     , multipart >= 0.1.1 && < 0.2
     , random >= 1.0 && < 1.2
     , rest-stringmap == 0.2.*
-    , rest-types == 1.13.*
+    , rest-types == 1.14.*
     , safe >= 0.2 && < 0.4
-    , semigroups == 0.16.*
     , split >= 0.1 && < 0.3
     , text >= 0.11 && < 1.3
     , transformers >= 0.2 && < 0.5
diff --git a/src/Rest/Dictionary/Combinators.hs b/src/Rest/Dictionary/Combinators.hs
--- a/src/Rest/Dictionary/Combinators.hs
+++ b/src/Rest/Dictionary/Combinators.hs
@@ -147,7 +147,7 @@
 
 -- | Allow file output using a combination of the raw data and a mime type.
 
-fileO :: Dict h p i Nothing e -> Dict h p i (Just (ByteString, String)) e
+fileO :: Dict h p i Nothing e -> Dict h p i (Just (ByteString, String, Bool)) e
 fileO = L.set outputs (Dicts [FileO])
 
 -- | Allow output as XML using the `XmlPickler` type class.
diff --git a/src/Rest/Dictionary/Types.hs b/src/Rest/Dictionary/Types.hs
--- a/src/Rest/Dictionary/Types.hs
+++ b/src/Rest/Dictionary/Types.hs
@@ -157,7 +157,7 @@
 -- combination of input type to output type.
 
 data Output o where
-  FileO      ::                                         Output (ByteString, String)
+  FileO      ::                                         Output (ByteString, String, Bool)
   RawXmlO    ::                                         Output ByteString
   JsonO      :: (Typeable o, ToJSON o, JSONSchema o) => Output o
   XmlO       :: (Typeable o, XmlPickler o)           => Output o
diff --git a/src/Rest/Driver/Perform.hs b/src/Rest/Driver/Perform.hs
--- a/src/Rest/Driver/Perform.hs
+++ b/src/Rest/Driver/Perform.hs
@@ -319,12 +319,15 @@
         tryD (StringO    : _ ) StringFormat = contentType StringFormat >> ok (UTF8.fromString v)
         tryD (MultipartO : _ ) _            = outputMultipart v
         tryD (FileO      : _ ) FileFormat   =
-          do let ext = (reverse . takeWhile (/='.') . reverse) $ snd v
+          do let (content, filename, isAttachment) = v
+                 ext = (reverse . takeWhile (/='.') . reverse) filename
              mime <- fromMaybe "application/octet-stream" <$> lookupMimeType (map toLower ext)
              setHeader "Content-Type" mime
              setHeader "Cache-Control" "max-age=604800"
-             setHeader "Content-Disposition" ("filename=\"" ++ escapeQuotes (snd v) ++ "\"")
-             ok (fst v)
+             setHeader "Content-Disposition" (  (if isAttachment then "attachment; " else "")
+                                             ++ "filename=\"" ++ escapeQuotes filename ++ "\""
+                                             )
+             ok content
         tryD []                t            = unsupportedFormat t
         tryD (_          : xs) t            = tryD xs t
     ok r = setResponseCode 200 >> return r
diff --git a/src/Rest/Error.hs b/src/Rest/Error.hs
--- a/src/Rest/Error.hs
+++ b/src/Rest/Error.hs
@@ -15,9 +15,7 @@
   ) where
 
 import Control.Applicative
-import Control.Monad.Error.Class
-import Control.Monad.Trans.Except
-import Data.Semigroup
+import Control.Monad.Except
 
 import Rest.Types.Error
 
@@ -44,13 +42,7 @@
 domainReason = CustomReason . DomainReason
 
 infixl 3 >|<
--- | Combine two ExceptT computations yielding the last error if both fail.
+-- | Try two ExceptT computations left to right yielding the last error if both fail.
 -- This prevents the need for a Semigroup or Monoid instance for the error type, which is necessary if using (<!>) or (<|>) respectively.
-(>|<) :: (Applicative m, Monad m) => ExceptT e m a -> ExceptT e m a -> ExceptT e m a
-a >|< b = mapE getLast (mapE Last a <!> mapE Last b)
-  where
-    ExceptT m <!> ExceptT n = ExceptT $ do
-      v <- m
-      case v of
-        Left e -> fmap (either (Left . (<>) e) Right) n
-        Right x -> return (Right x)
+(>|<) :: (Monad m) => ExceptT f m a -> ExceptT e m a -> ExceptT e m a
+ExceptT m >|< ExceptT n = ExceptT $ m >>= either (const n) (return . Right)
