diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,40 @@
 # Change log
 
+Unreleased
+====
+
+0.4.0 — Nov 6, 2018
+=====
+
+* [#70](https://github.com/kowainik/relude/issues/70):
+  Reexport `Contravariant` for GHC >= 8.6.1.
+* [#103](https://github.com/kowainik/relude/pull/104):
+  Drop `utf8-string` dependency and improve performance of conversion functions.
+* [#98](https://github.com/kowainik/relude/issues/98):
+  Reexport `Bifoldable` related stuff from `base`.
+* [#99](https://github.com/kowainik/relude/issues/99):
+  Reexport `Bitraversable` related stuff from `base`.
+* [#100](https://github.com/kowainik/relude/issues/100):
+  Add `Relude.Extra.Validation` with `Validation`data type.
+* [#89](https://github.com/kowainik/relude/issues/81):
+  Add `Relude.Extra.Type` module containing a `typeName` function.
+* [#92](https://github.com/kowainik/relude/issues/92)
+  Add `Relude.Extra.Tuple` module, containing
+  `dupe`, `mapToFst`, `mapToSnd`, and `mapBoth` functions.
+* [#97](https://github.com/kowainik/relude/issues/97):
+  Add `(&&^)` and `(||^)` operators.
+* [#81](https://github.com/kowainik/relude/issues/81):
+  Add `asumMap` to `Foldable` functions.
+* [#80](https://github.com/kowainik/relude/issues/80):
+  Add hlint rules for `whenLeft`, `whenLeftM`, `whenRight` and `whenRightM`.
+* [#79](https://github.com/kowainik/relude/issues/79):
+  Add HLint rules for `One` typeclass.
+* Remove `openFile` and `hClose`.
+* [#83](https://github.com/kowainik/relude/pull/83):
+  Make documentation for `nub` functions prettier.
+* [#109](https://github.com/kowainik/relude/issues/109):
+  Use Dhall v3.0.0 for hlint file generation.
+
 0.3.0
 =====
 
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,53 +1,53 @@
-# Contributing to `relude`
+# Contributing to the Kowainik repositories
 
 ## :wave: Greetings Traveler!
 
-We're glad you're reading this, we really appreciate the effort you're
-putting in. Thank you for your help in making this library awesome! :sparkles:
+We are delighted you're reading this, and we appreciate the effort you're
+taking to make our projects awesome! :sparkles:
 
-### How to contribute
+## How to contribute
 
-#### Report bugs or feature request
+### :bug: Report bugs or feature request :bulb:
 
-If you have found any bugs or have proposals on how to make this project better,
-don't hesitate to create issues
-[here](https://github.com/kowainik/relude/issues/new) in free format.
+If you discover a bug or have any proposals on how to make this project better
+don't hesitate to create an issue [here](../../issues/new) in a free format.
 
-#### Create a PR
+### Create a PR
 
-We love receiving pull requests from everyone. But, please, don't create a PR
-without a corresponding issue. It's always better to discuss your future
-work first. Even if such an issue exists it's still better to express your willing
-to do that issue under comment section. Thus you will show that you're doing
-that issue, and nobody else will accidentally do it in parallel with you. Furthermore,
-you also can discuss the best way to implement that issue!
+We love to receive pull requests from everyone! It's usually a good idea
+to tell about your intention to work on something under the corresponding
+issue, so everyone is aware that you're on it. If there's no such issue — simply
+create a new one!
 
-To get started with this you should first fork, then clone the repo:
+To get started with the Pull Request implementation you should first 
+[fork](../../fork), then clone the repo:
 
-    git clone git@github.com:your-username/relude.git
+    git clone git@github.com:your-username/project-name.git
 
-Make your changes and consider the following check list to go through before submitting your pull request.
+Make your changes and consider the following checklist to go through 
+before submitting your pull request.
 
-#### :white_check_mark: Check list
+### :white_check_mark: Check list
+- [ ] New/fixed features work as expected (Bonus points for the new tests).
+- [ ] There are no warnings during compilation.
+- [ ] `hlint .` output is: _No Hints_ (see [`hlint`][hlint] tool docs).
+- [ ] The code is formatted with the [`stylish-haskell`][stylish-tool] tool 
+      using [stylish-haskell.yaml][stylish] file in the repository.
+- [ ] The code style of the files you changed is preserved (for more specific 
+      details on our style guide check [this document][style-guide]).
+- [ ] Commit messages are in the proper format.
+      Start the first line of the commit with the issue number in square parentheses.
+      
+    **_Example:_** `[#42] Upgrade upper bounds of 'base'`
 
-- [ ] Project compiles
-- [ ] New/fixed features work as expected
-- [ ] Old features do not break after the change
-- [ ] All new and existing tests pass
-- [ ] [`stylish-haskell`](https://github.com/kowainik/org/blob/master/.stylish-haskell.yaml)
-      with config in this repo root was used to format code
-- [ ] _Recommended:_ Commit messages are in the proper format. If the commit
-  addresses an issue start the first line of the commit with the issue number in
-  square parentheses.
-  + **_Example:_** `[#42] Short commit description`
-- [ ] All changes are reflected in `.hlint.yaml` (Use `hlint/hlint.dhall` to make changes).
+After all above is done commit and push to your fork.
+Now you are ready to [submit a pull request](../../compare).
 
-If you fix bugs or add new features, please add tests.
 
-After everything above is done, commit and push to your fork.
-Now you are ready to [submit a pull request][pr]!
-
 ----------
-Thanks for spending time on reading this contributing guide! :sparkling_heart:
+Thanks for spending your time on reading this contributing guide! :sparkling_heart:
 
-[pr]: https://github.com/kowainik/relude/compare/
+[stylish]: .stylish-haskell.yaml
+[stylish-tool]: http://hackage.haskell.org/package/stylish-haskell
+[hlint]: http://hackage.haskell.org/package/hlint
+[style-guide]: https://github.com/kowainik/org/blob/master/style-guide.md#haskell-style-guide
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -33,7 +33,7 @@
 4. **Minimalism** (low number of dependencies). We don't force users of `relude` to
    stick to some specific lens or text formatting or logging library.
 5. **Convenience** (like lifted to `MonadIO` functions, more reexports). But we
-   want to bring common types and functions (like `containers` and `bytestrng`)
+   want to bring common types and functions (like `containers` and `bytestring`)
    into scope because they are used in almost every application anyways.
 6. **Provide excellent documentation.**
    * Tutorial
@@ -61,6 +61,7 @@
 3. [Reexports.](#reexports-)
 4. [What's new?](#whats-new-)
 6. [Migration guide.](#migration-guide-)
+7. [For developers.](#for-developers-)
 
 This is neither a tutorial on _Haskell_ nor tutorial on each function contained
 in `Relude`. For detailed documentation of every function together with examples
@@ -78,7 +79,8 @@
 
 1. Replace `base` dependency with corresponding version of `base-noprelude` in
    your `.cabal` file.
-2. Add the following `Prelude` module to your project (both to filesystem and to `exposed-modules`):
+2. Add a `relude` dependency to your `.cabal` file.
+3. Add the following `Prelude` module to your project (both to filesystem and to `exposed-modules`):
    ```haskell
    module Prelude
           ( module Relude
@@ -88,7 +90,7 @@
    ```
    > **NOTE:** if you use [`summoner`](https://github.com/kowainik/summoner) to generate Haskell project,
    > this tool can automatically create such structure for you when you specify custom prelude.
-3. Optionally modify your `Prelude` to include more or less functions. Probably
+4. Optionally modify your `Prelude` to include more or less functions. Probably
    you want to hide something from `Relude` module. Or maybe you want to add
    something from `Relude.Extra.*` modules!
 
@@ -291,6 +293,8 @@
 
 * `Foldable1` typeclass that contains generalized interface for folding
   non-empty structures like `NonEmpty`.
+* `Validation` data type as an alternative to `Either` when you want to combine
+  all errors.
 
 Explore `Extra` modules: [`Relude.Extra`](src/Relude/Extra/)
 
@@ -337,9 +341,9 @@
    + Use `(putStr[Ln]|readFile|writeFile|appendFile)[Text|LText|BS|LBS]` functions.
 6. Run `hlint` using `.hlint.yaml` file from `relude` package to cleanup code and imports.
 
-### For Developers
+## For Developers [↑](#structure-of-this-tutorial)
 
-#### Generating .hlint.yaml
+### Generating .hlint.yaml
 
 Note, that we are using custom `hlint` setting which are `Relude` specific. To
 keep it up to date don't forget to reflect your changes in this file. We are
@@ -351,6 +355,9 @@
 $ cabal new-install dhall-json
 ```
 
+Dhall 3.0.0 is required, so make sure that the previous command installed
+dhall-json >= 1.2.4.
+
 To generate `hlint` file:
 
 ```shell
@@ -363,6 +370,11 @@
 $ hlint test/Spec.hs
 ```
 
-### Acknowledgement
+See our blog post where we describe the details of the implementation for this solution:
+
+* [Dhall To HLint](https://kowainik.github.io/posts/2018-09-09-dhall-to-hlint)
+
+
+## Acknowledgement
 
 Icons made by [Freepik](http://www.freepik.com) from [www.flaticon.com](https://www.flaticon.com/) is licensed by [CC 3.0 BY](http://creativecommons.org/licenses/by/3.0/).
diff --git a/relude.cabal b/relude.cabal
--- a/relude.cabal
+++ b/relude.cabal
@@ -1,6 +1,6 @@
 cabal-version:       2.0
 name:                relude
-version:             0.3.0
+version:             0.4.0
 synopsis:            Custom prelude from Kowainik
 description:
     == Goals
@@ -57,6 +57,7 @@
 tested-with:         GHC == 8.0.2
                    , GHC == 8.2.2
                    , GHC == 8.4.3
+                   , GHC == 8.6.1
 extra-doc-files:     CHANGELOG.md
                    , CONTRIBUTING.md
                    , README.md
@@ -110,13 +111,16 @@
                                Relude.String.Reexport
 
                            -- not exported by default
-                           Relude.Extra.Bifunctor
+                           Relude.Extra.Bifunctor                          
                            Relude.Extra.CallStack
                            Relude.Extra.Enum
                            Relude.Extra.Foldable1
                            Relude.Extra.Group
                            Relude.Extra.Map
                            Relude.Extra.Newtype
+                           Relude.Extra.Tuple
+                           Relude.Extra.Type
+                           Relude.Extra.Validation
                            Relude.Unsafe
 
   ghc-options:         -Wall
@@ -133,11 +137,10 @@
                      , ghc-prim >= 0.4.0.0 && < 0.6
                      , hashable ^>= 1.2
                      , mtl ^>= 2.2
-                     , stm ^>= 2.4
+                     , stm >= 2.4 && < 2.6
                      , text ^>= 1.2
                      , transformers ^>= 0.5
                      , unordered-containers >= 0.2.7 && < 0.3
-                     , utf8-string ^>= 1.0
 
   default-language:    Haskell2010
   default-extensions:  NoImplicitPrelude
@@ -154,7 +157,6 @@
                      , relude
                      , bytestring
                      , text
-                     , utf8-string
                      , hedgehog >= 0.6
                      , tasty
                      , tasty-hedgehog
diff --git a/src/Relude.hs b/src/Relude.hs
--- a/src/Relude.hs
+++ b/src/Relude.hs
@@ -83,10 +83,15 @@
   'CallStack'.
 * __"Relude.Extra.Enum"__: extra utilities for types that implement 'Bounded'
   and 'Enum' constraints.
+* __"Relude.Extra.Foldable1"__: 'Foldable1' typeclass like 'Foldable' but for
+  non-empty structures.
 * __"Relude.Extra.Group"__: grouping functions, polymorphic on return @Map@ type.
 * __"Relude.Extra.Map"__: typeclass for @Map@-like data structures.
 * __"Relude.Extra.Newtype"__: generic functions that automatically work for any
   @newtype@.
+* __"Relude.Extra.Tuple"__: functions for working with tuples.
+* __"Relude.Extra.Type"__: functions for inspecting and working with types.
+* __"Relude.Extra.Validation"__: 'Validation' data type.
 * __"Relude.Unsafe"__: unsafe partial functions (produce 'error') for lists and
   'Maybe'.
 -}
diff --git a/src/Relude/Bool/Guard.hs b/src/Relude/Bool/Guard.hs
--- a/src/Relude/Bool/Guard.hs
+++ b/src/Relude/Bool/Guard.hs
@@ -13,15 +13,18 @@
        , ifM
        , unlessM
        , whenM
+       , (&&^)
+       , (||^)
        ) where
 
-import Relude.Bool.Reexport (Bool, guard, unless, when)
+import Relude.Bool.Reexport (Bool (..), guard, unless, when)
 import Relude.Function (flip)
-import Relude.Monad (Monad, MonadPlus, (>>=))
+import Relude.Monad (Monad, return, MonadPlus, (>>=))
 
 -- $setup
 -- >>> import Relude.Applicative (pure)
 -- >>> import Relude.Bool.Reexport (Bool (..))
+-- >>> import Relude.Debug (error)
 -- >>> import Relude.Function (($))
 -- >>> import Relude.Monad (Maybe (..))
 -- >>> import Relude.Print (putTextLn)
@@ -73,3 +76,19 @@
 guardM :: MonadPlus m => m Bool -> m ()
 guardM f = f >>= guard
 {-# INLINE guardM #-}
+
+-- | Monadic version of 'Data.Bool.(&&)' operator.
+--
+-- >>> Just False &&^ error "Shouldn't be evaluated"
+-- Just False
+(&&^) :: Monad m => m Bool -> m Bool -> m Bool
+(&&^) e1 e2 = ifM e1 e2 (return False)
+{-# INLINE (&&^) #-}
+
+-- | Monadic version of 'Data.Bool.(||)' operator.
+--
+-- >>> Just True ||^ error "Shouldn't be evaluated"
+-- Just True
+(||^) :: Monad m => m Bool -> m Bool -> m Bool
+(||^) e1 e2 = ifM e1 (return True) e2
+{-# INLINE (||^) #-}
diff --git a/src/Relude/Extra/Tuple.hs b/src/Relude/Extra/Tuple.hs
new file mode 100644
--- /dev/null
+++ b/src/Relude/Extra/Tuple.hs
@@ -0,0 +1,62 @@
+{- |
+Copyright:  (c) 2018 Kowainik
+License:    MIT
+Maintainer: Kowainik <xrom.xkov@gmail.com>
+
+Contains utility functions for working with tuples.
+-}
+
+module Relude.Extra.Tuple
+       ( dupe
+       , mapToFst
+       , mapToSnd
+       , mapBoth
+       ) where
+
+-- $setup
+-- >>> import Relude
+
+{- | Creates a tuple by pairing something with itself.
+
+>>> dupe "foo"
+("foo","foo")
+>>> dupe ()
+((),())
+-}
+dupe :: a -> (a, a)
+dupe a = (a, a)
+{-# INLINE dupe #-}
+
+{- | Apply a function, with the result in the fst slot,
+and the value in the other.
+
+
+A dual to 'mapToSnd'
+
+>>> mapToFst (+1) 10
+(11,10)
+-}
+mapToFst :: (a -> b) -> a -> (b, a)
+mapToFst f a = (f a, a)
+{-# INLINE mapToFst #-}
+
+{- | Apply a function, with the result in the second slot,
+and the value in the other.
+
+A dual to 'mapToFst'.
+
+>>> mapToSnd (+1) 10
+(10,11)
+-}
+mapToSnd :: (a -> b) -> a -> (a, b)
+mapToSnd f a = (a, f a)
+{-# INLINE mapToSnd #-}
+
+{- | Maps a function over both elements of a tuple.
+
+>>> mapBoth ("Hello " <>) ("Alice", "Bob")
+("Hello Alice","Hello Bob")
+-}
+mapBoth :: (a -> b) -> (a, a) -> (b, b)
+mapBoth f (a1, a2) = (f a1, f a2)
+{-# INLINE mapBoth #-}
diff --git a/src/Relude/Extra/Type.hs b/src/Relude/Extra/Type.hs
new file mode 100644
--- /dev/null
+++ b/src/Relude/Extra/Type.hs
@@ -0,0 +1,45 @@
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE CPP                 #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{- |
+Copyright:  (c) 2018 Kowainik
+License:    MIT
+Maintainer: Kowainik <xrom.xkov@gmail.com>
+
+Contains useful functions to work with Types.
+-}
+
+module Relude.Extra.Type
+       ( typeName
+       ) where
+
+import Relude
+
+#if ( __GLASGOW_HASKELL__ >= 822 )
+import Type.Reflection (Typeable, typeRep)
+#else
+import Data.Typeable (Typeable, typeRep)
+#endif
+
+{- | Gets a string representation of a type.
+
+__NOTE:__ This must be used with __TypeApplications__ language extension.
+
+>>> typeName @()
+"()"
+>>> typeName @Int
+"Int"
+>>> typeName @String
+"[Char]"
+>>> typeName @(Maybe Int)
+"Maybe Int"
+-}
+typeName :: forall a. Typeable a => Text
+#if ( __GLASGOW_HASKELL__ >= 822 )
+typeName = show (typeRep @a)
+#else
+typeName = show (typeRep (Proxy @a))
+#endif
+{-# INLINE typeName #-}
diff --git a/src/Relude/Extra/Validation.hs b/src/Relude/Extra/Validation.hs
new file mode 100644
--- /dev/null
+++ b/src/Relude/Extra/Validation.hs
@@ -0,0 +1,182 @@
+{-# LANGUAGE CPP          #-}
+{-# LANGUAGE InstanceSigs #-}
+{-# LANGUAGE LambdaCase   #-}
+
+{- |
+Copyright: (c) 2014 Chris Allen, Edward Kmett
+           (c) 2018 Kowainik
+License:   MIT
+Maintainer: Kowainik <xrom.xkov@gmail.com>
+
+Monoidal 'Validation' sibling to 'Either'.
+-}
+
+module Relude.Extra.Validation
+       ( Validation(..)
+       , validationToEither
+       , eitherToValidation
+       ) where
+
+import Relude
+
+-- $setup
+-- >>> :set -XTypeApplications -XOverloadedStrings
+
+-- | 'Validation' is 'Either' with a Left that is a 'Monoid'
+data Validation e a
+    = Failure e
+    | Success a
+    deriving (Eq, Ord, Show)
+
+instance Functor (Validation e) where
+    fmap :: (a -> b) -> Validation e a -> Validation e b
+    fmap _ (Failure e) = Failure e
+    fmap f (Success a) = Success (f a)
+    {-# INLINE fmap #-}
+
+    (<$) :: a -> Validation e b -> Validation e a
+    x <$ Success _ = Success x
+    _ <$ Failure e = Failure e
+    {-# INLINE (<$) #-}
+
+{- | __Examples__
+
+>>> let fa = Success (*3) :: Validation [Text] (Int -> Int)
+>>> let ga = Success (*4) :: Validation [Text] (Int -> Int)
+>>> let a = Success 1 :: Validation [Text] Int
+>>> let b = Success 7 :: Validation [Text] Int
+>>> let c = Failure ["Not correct"] :: Validation [Text] Int
+>>> let d = Failure ["Not correct either"] :: Validation [Text] Int
+
+>>> fa <*> b
+Success 21
+
+>>> fa <*> c
+Failure ["Not correct"]
+
+>>> c *> d *> b
+Failure ["Not correct","Not correct either"]
+
+>>> liftA2 (+) a b
+Success 8
+
+>>> liftA2 (+) a c
+Failure ["Not correct"]
+-}
+instance Semigroup e => Applicative (Validation e) where
+    pure :: a -> Validation e a
+    pure = Success
+    {-# INLINE pure #-}
+
+#if MIN_VERSION_base(4,10,0)
+    liftA2 :: (a -> b -> c) -> Validation e a -> Validation e b -> Validation e c
+    liftA2 _ (Failure el) (Failure er) = Failure (el <> er)
+    liftA2 _ (Failure e)  (Success _)  = Failure e
+    liftA2 _ (Success _)  (Failure e)  = Failure e
+    liftA2 f (Success a)  (Success b)  = Success (f a b)
+    {-# INLINE liftA2 #-}
+#endif
+
+    (<*>) :: Validation e (a -> b) -> Validation e a -> Validation e b
+    Failure e <*> b = Failure $ case b of
+                                  Failure e' -> e <> e'
+                                  Success _  -> e
+    Success _ <*> Failure e  = Failure e
+    Success f <*> Success a = Success (f a)
+    {-# INLINE (<*>) #-}
+
+    (*>) :: Validation e a -> Validation e b -> Validation e b
+    Failure el *> Failure er = Failure (el <> er)
+    Failure e  *> Success _  = Failure e
+    Success _  *> Failure e  = Failure e
+    Success _  *> Success b  = Success b
+    {-# INLINE (*>) #-}
+
+    (<*) :: Validation e a -> Validation e b -> Validation e a
+    Failure el <* Failure er = Failure (el <> er)
+    Failure e  <* Success _  = Failure e
+    Success _  <* Failure e  = Failure e
+    Success a  <* Success _  = Success a
+    {-# INLINE (<*) #-}
+
+instance (Semigroup e, Monoid e) => Alternative (Validation e) where
+    empty :: Validation e a
+    empty = Failure mempty
+    {-# INLINE empty #-}
+
+    (<|>) :: Validation e a -> Validation e a -> Validation e a
+    s@Success{} <|> _ = s
+    _ <|> s@Success{} = s
+    Failure e <|> Failure e' = Failure (e <> e')
+    {-# INLINE (<|>) #-}
+
+instance Foldable (Validation e) where
+    fold :: Monoid m => Validation e m -> m
+    fold (Success a) = a
+    fold (Failure _) = mempty
+    {-# INLINE fold #-}
+
+    foldMap :: Monoid m => (a -> m) -> Validation e a -> m
+    foldMap _ (Failure _) = mempty
+    foldMap f (Success a) = f a
+    {-# INLINE foldMap #-}
+
+    foldr :: (a -> b -> b) -> b -> Validation e a -> b
+    foldr f x (Success a) = f a x
+    foldr _ x (Failure _) = x
+    {-# INLINE foldr #-}
+
+instance Traversable (Validation e) where
+    traverse :: Applicative f => (a -> f b) -> Validation e a -> f (Validation e b)
+    traverse f (Success a) = Success <$> f a
+    traverse _ (Failure e) = pure (Failure e)
+    {-# INLINE traverse #-}
+
+    sequenceA :: Applicative f => Validation e (f a) -> f (Validation e a)
+    sequenceA = traverse id
+    {-# INLINE sequenceA #-}
+
+instance Bifunctor Validation where
+    bimap :: (e -> d) -> (a -> b) -> Validation e a -> Validation d b
+    bimap f _ (Failure e) = Failure (f e)
+    bimap _ g (Success a) = Success (g a)
+    {-# INLINE bimap #-}
+
+    first :: (e -> d) -> Validation e a -> Validation d a
+    first f (Failure e) = Failure (f e)
+    first _ (Success a) = Success a
+    {-# INLINE first #-}
+
+    second :: (a -> b) -> Validation e a -> Validation e b
+    second _ (Failure e) = Failure e
+    second g (Success a) = Success (g a)
+    {-# INLINE second #-}
+
+#if MIN_VERSION_base(4,10,0)
+instance Bifoldable Validation where
+    bifoldMap :: Monoid m => (e -> m) -> (a -> m) -> Validation e a -> m
+    bifoldMap f _ (Failure e) = f e
+    bifoldMap _ g (Success a) = g a
+    {-# INLINE bifoldMap #-}
+
+instance Bitraversable Validation where
+    bitraverse :: Applicative f
+               => (e -> f d) -> (a -> f b) -> Validation e a -> f (Validation d b)
+    bitraverse f _ (Failure e) = Failure <$> f e
+    bitraverse _ g (Success a) = Success <$> g a
+    {-# INLINE bitraverse #-}
+#endif
+
+-- | Transform a 'Validation' into an 'Either'.
+validationToEither :: Validation e a -> Either e a
+validationToEither = \case
+    Failure e -> Left e
+    Success a -> Right a
+{-# INLINE validationToEither #-}
+
+-- | Transform an 'Either' into a 'Validation'.
+eitherToValidation :: Either e a -> Validation e a
+eitherToValidation = \case
+    Left e  -> Failure e
+    Right a -> Success a
+{-# INLINE eitherToValidation #-}
diff --git a/src/Relude/Foldable/Fold.hs b/src/Relude/Foldable/Fold.hs
--- a/src/Relude/Foldable/Fold.hs
+++ b/src/Relude/Foldable/Fold.hs
@@ -20,6 +20,7 @@
 module Relude.Foldable.Fold
        ( flipfoldl'
        , foldMapA
+       , asumMap
        , foldMapM
        , sum
        , product
@@ -39,7 +40,7 @@
 
 import GHC.TypeLits (ErrorMessage (..), TypeError)
 
-import Relude.Applicative (Applicative (..), pure)
+import Relude.Applicative (Alternative, Applicative (..), pure)
 import Relude.Base (Constraint, Eq, IO, Num (..), Type, ($!))
 import Relude.Bool (Bool (..))
 import Relude.Container.Reexport (HashSet, Set)
@@ -47,7 +48,7 @@
 import Relude.Function (flip, (.))
 import Relude.Functor ((<$>))
 import Relude.Monad.Reexport (Monad (..))
-import Relude.Monoid (Monoid (..))
+import Relude.Monoid (Alt(..), Monoid (..))
 
 import qualified Data.Foldable as F
 
@@ -75,6 +76,14 @@
   where
     step a mb = mappend <$> f a <*> mb
 {-# INLINE foldMapA #-}
+
+{- | Alternative version of @asum@
+>>> asumMap (\x -> if x > 2 then Just x else Nothing) [1..3]
+Just 3
+-}
+asumMap :: (Foldable f, Alternative m) => (a -> m b) -> f a -> m b
+asumMap f = getAlt . foldMap (Alt . f)
+{-# INLINE asumMap #-}
 
 {- | Polymorphic version of @concatMapM@ function.
 
diff --git a/src/Relude/Foldable/Reexport.hs b/src/Relude/Foldable/Reexport.hs
--- a/src/Relude/Foldable/Reexport.hs
+++ b/src/Relude/Foldable/Reexport.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE CPP #-}
+
 {- |
 Copyright:  (c) 2018 Kowainik
 License:    MIT
@@ -9,9 +11,20 @@
 module Relude.Foldable.Reexport
        ( module Data.Foldable
        , module Data.Traversable
+#if MIN_VERSION_base(4,10,0)
+       , module Data.Bifoldable
+       , module Data.Bitraversable
+#endif
        ) where
 
 import Data.Foldable (Foldable (fold, foldMap, foldl', foldr, length, null, toList), all, and, any,
                       asum, concat, concatMap, find, foldlM, forM_, for_, mapM_, or, sequenceA_,
                       sequence_, traverse_)
 import Data.Traversable (Traversable (..), forM, mapAccumL, mapAccumR)
+#if MIN_VERSION_base(4,10,0)
+import Data.Bifoldable (Bifoldable (..), biList, biall, biand,
+                        biany, biasum, bielem, bifind, bifoldl', bifoldlM, bifoldr',
+                        bifoldrM, bifor_, bilength, binull, bior, bisequence_,
+                        bitraverse_)
+import Data.Bitraversable (Bitraversable (..), bifoldMapDefault, bifor, bimapDefault, bisequence)
+#endif
diff --git a/src/Relude/Functor/Reexport.hs b/src/Relude/Functor/Reexport.hs
--- a/src/Relude/Functor/Reexport.hs
+++ b/src/Relude/Functor/Reexport.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP  #-}
 {-# LANGUAGE Safe #-}
 
 {- |
@@ -15,9 +16,18 @@
        , module Data.Functor
        , module Data.Functor.Compose
        , module Data.Functor.Identity
+#if MIN_VERSION_base(4,12,0)
+       , module Data.Functor.Contravariant
+#endif
        ) where
 
 import Data.Bifunctor (Bifunctor (..))
 import Data.Functor (Functor (..), void, ($>), (<$>))
 import Data.Functor.Compose (Compose (..))
 import Data.Functor.Identity (Identity (..))
+
+#if MIN_VERSION_base(4,12,0)
+import Data.Functor.Contravariant (Comparison (..), Contravariant (..), Equivalence (..), Op (..),
+                                   Predicate (..), comparisonEquivalence, defaultComparison,
+                                   defaultEquivalence, phantom, ($<), (>$$<), (>$<))
+#endif
diff --git a/src/Relude/Lifted/File.hs b/src/Relude/Lifted/File.hs
--- a/src/Relude/Lifted/File.hs
+++ b/src/Relude/Lifted/File.hs
@@ -12,11 +12,9 @@
        ( readFile
        , writeFile
        , appendFile
-       , openFile
-       , hClose
        ) where
 
-import Relude.Base (FilePath, Handle, IO, IOMode, String)
+import Relude.Base (FilePath, IO, String)
 import Relude.Function ((.))
 import Relude.Monad.Reexport (MonadIO (..))
 
@@ -40,15 +38,3 @@
 appendFile p = liftIO . IO.appendFile p
 {-# SPECIALIZE appendFile :: FilePath -> String -> IO () #-}
 {-# INLINE appendFile #-}
-
--- | Lifted version of 'IO.openFile'.
-openFile :: MonadIO m => FilePath -> IOMode -> m Handle
-openFile p = liftIO . IO.openFile p
-{-# SPECIALIZE openFile :: FilePath -> IOMode -> IO Handle #-}
-{-# INLINE openFile #-}
-
--- | Lifted version of 'IO.hClose'.
-hClose :: MonadIO m => Handle -> m ()
-hClose = liftIO . hClose
-{-# SPECIALIZE hClose :: Handle -> IO () #-}
-{-# INLINE hClose #-}
diff --git a/src/Relude/Nub.hs b/src/Relude/Nub.hs
--- a/src/Relude/Nub.hs
+++ b/src/Relude/Nub.hs
@@ -43,7 +43,7 @@
 
 import qualified Data.Set as Set
 
-{- | Like 'Prelude.nub' but runs in @O(n * log n)@ time and requires 'Ord'.
+{- | Like 'Prelude.nub' but runs in \( O(n \log n) \)  time and requires 'Ord'.
 
 >>> ordNub [3, 3, 3, 2, 2, -1, 1]
 [3,2,-1,1]
@@ -58,7 +58,7 @@
       then go s xs
       else x : go (Set.insert x s) xs
 
-{- | Like 'Prelude.nub' but runs in @O(n * log_16(n))@ time and requires 'Hashable'.
+{- | Like 'Prelude.nub' but runs in \( O(n \log_{16} n) \)  time and requires 'Hashable'.
 
 >>> hashNub [3, 3, 3, 2, 2, -1, 1]
 [3,2,-1,1]
@@ -73,7 +73,7 @@
       then go s xs
       else x : go (HashSet.insert x s) xs
 
-{- | Like 'ordNub' but also sorts a list.
+{- | Like 'ordNub' runs in \( O(n \log n) \)  but also sorts a list.
 
 >>> sortNub [3, 3, 3, 2, 2, -1, 1]
 [-1,1,2,3]
@@ -82,7 +82,7 @@
 sortNub :: (Ord a) => [a] -> [a]
 sortNub = Set.toList . Set.fromList
 
-{- | Like 'hashNub' but has better performance and also doesn't save the order.
+{- | Like 'hashNub' runs in \( O(n \log_{16} n) \) but has better performance; it doesn't save the order.
 
 >>> unstableNub [3, 3, 3, 2, 2, -1, 1]
 [1,2,3,-1]
diff --git a/src/Relude/String/Conversion.hs b/src/Relude/String/Conversion.hs
--- a/src/Relude/String/Conversion.hs
+++ b/src/Relude/String/Conversion.hs
@@ -48,8 +48,6 @@
 
 import qualified Data.ByteString as B
 import qualified Data.ByteString.Lazy as LB
-import qualified Data.ByteString.Lazy.UTF8 as LBU
-import qualified Data.ByteString.UTF8 as BU
 import qualified Data.Text as T
 import qualified Data.Text.Encoding as T
 import qualified Data.Text.Encoding.Error as T
@@ -101,8 +99,8 @@
     decodeUtf8Strict :: b -> Either T.UnicodeException a
 
 instance ConvertUtf8 String B.ByteString where
-    encodeUtf8 = BU.fromString
-    decodeUtf8 = BU.toString
+    encodeUtf8 = T.encodeUtf8 . T.pack
+    decodeUtf8 = T.unpack . T.decodeUtf8
     decodeUtf8Strict = (T.unpack <$>) . decodeUtf8Strict
 
 instance ConvertUtf8 T.Text B.ByteString where
@@ -114,10 +112,11 @@
     encodeUtf8 = LB.toStrict . encodeUtf8
     decodeUtf8 = LT.decodeUtf8With T.lenientDecode . LB.fromStrict
     decodeUtf8Strict = decodeUtf8Strict . LB.fromStrict
-
+-- | Converting 'String' to 'LB.ByteString' might be a slow operation.
+-- Consider using lazy bytestring at first place.
 instance ConvertUtf8 String LB.ByteString where
-    encodeUtf8 = LBU.fromString
-    decodeUtf8 = LBU.toString
+    encodeUtf8 = LT.encodeUtf8 . LT.pack
+    decodeUtf8 = LT.unpack . LT.decodeUtf8
     decodeUtf8Strict = (T.unpack <$>) . decodeUtf8Strict
 
 instance ConvertUtf8 T.Text LB.ByteString where
