diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,12 @@
 and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
 
 ## [Unreleased]
+## Added
+- Error message is more useful.
+- Examples.
+
+### Changed
+- Documentation added.
 
 ## [0.1.0.0] - 2018-01-22
 ### Added
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,3 +1,76 @@
 # aeson-picker
 
+[![Travis](https://img.shields.io/travis/ozzzzz/aeson-picker.svg)](https://travis-ci.org/ozzzzz/aeson-picker)
+[![hackage](https://img.shields.io/hackage/v/aeson-picker.svg)](https://hackage.haskell.org/package/aeson-picker)
+[![hackage-deps](https://img.shields.io/hackage-deps/v/aeson-picker.svg)](https://hackage.haskell.org/package/aeson-picker)
+
 Tiny library to get fields from JSON format
+
+Common use is the following:
+```
+JSON |-- FIELDS :: EXPECTED TYPE
+Text |-- [Text] :: a
+```
+So operator `(|--)` gets JSON (represented as `Text`), "route" to field inside JSON (represented as `[Text]`), and tries to parse field from JSON with described route to expected type.
+If expected type can be deduced with type checker then it can be dropped down.
+
+A little bit safer operator is `(|-?)`. It returns not `a` but `Maybe a`.
+
+## Examples
+First, add extension (to not pack `String` to `Text` every time):
+```
+ghci>:set -XOverloadedStrings
+```
+
+Then you can try something simple (empty list means that you try to parse `Value` from the top JSON-level):
+```
+ghci>"5" |-- [] :: Int
+5
+ghci>"5" |-- [] :: Float
+5.0
+ghci>"5" |-- [] :: String
+"*** Exception: Data.Aeson.Picker: could not pick field with path: []
+```
+
+But what if field you are looking for somewhere inside JSON?
+That's why are you here.
+
+Let's try to get something from inside JSON:
+```
+ghci>"{\"a\": 5}" |-- ["a"] :: Int
+5
+```
+But be sure that the field is presented inside JSON:
+```
+ghci>"{\"a\": 5}" |-- ["b"] :: Int
+*** Exception: Data.Aeson.Picker: could not pick field with path: ["b"]
+```
+We can go deeper (as deep as you want):
+```
+ghci>"{\"outer\": {\"inner\": [1,2,3]}}" |-- ["outer", "inner"] :: [Int]
+[1,2,3]
+```
+But be sure that you JSON is really valid (by specification key in JSON should be `String`):
+```
+ghci>"{a: 5}" |-- ["a"] :: Int
+*** Exception: Data.Aeson.Picker: input json is not valid
+```
+
+If you want more "safe" picker, you can use another operator:
+```
+ghci>"5" |-? [] :: Maybe Int
+Just 5
+ghci>"{\"a\": 5}" |-? ["a"] :: Maybe Int
+Just 5
+ghci>"{\"a\": 5}" |-? ["b"] :: Maybe Int
+Nothing
+```
+
+In current logic even operator `(|-?)` will throw error if JSON is not valid:
+```
+ghci>"{a: 5}" |-? ["a"] :: Maybe Int
+*** Exception: Data.Aeson.Picker: input json is not valid
+```
+
+You can open issue if you do not think that it is right logic.
+
diff --git a/aeson-picker.cabal b/aeson-picker.cabal
--- a/aeson-picker.cabal
+++ b/aeson-picker.cabal
@@ -1,5 +1,5 @@
 name:           aeson-picker
-version:        0.1.0.0
+version:        0.1.0.1
 description:    Tiny library to get fields from JSON format
 homepage:       https://github.com/ozzzzz/aeson-picker#readme
 bug-reports:    https://github.com/ozzzzz/aeson-picker/issues
@@ -22,14 +22,13 @@
   location: https://github.com/ozzzzz/aeson-picker
 
 library
-  hs-source-dirs:  src
+  hs-source-dirs:   src
   exposed-modules:  Data.Aeson.Picker
-  other-modules:    Data.Aeson.Picker.Internal.Functions
   build-depends:    base >=4.7 && <5
-                  , aeson
-                  , lens
-                  , lens-aeson
-                  , text
+                  , aeson >= 1.2 && < 1.3
+                  , lens >= 4.15 && < 5
+                  , lens-aeson >= 1.0 && < 1.1
+                  , text >= 1.2 && < 1.3
   default-language: Haskell2010
 
 test-suite aeson-picker-test
@@ -39,6 +38,6 @@
   ghc-options: -threaded -rtsopts -with-rtsopts=-N
   build-depends:   base >=4.7 && <5
                  , aeson-picker
-                 , hspec
+                 , hspec >= 2.4 && < 2.5
                  , text
   default-language: Haskell2010
diff --git a/src/Data/Aeson/Picker.hs b/src/Data/Aeson/Picker.hs
--- a/src/Data/Aeson/Picker.hs
+++ b/src/Data/Aeson/Picker.hs
@@ -1,6 +1,78 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE RankNTypes        #-}
 module Data.Aeson.Picker
   ( (|--)
   , (|-?)
   ) where
 
-import Data.Aeson.Picker.Internal.Functions ((|--), (|-?))
+import           Control.Lens    (Traversal', (^?))
+import           Data.Aeson      (FromJSON (..), Result (..), Value, fromJSON)
+import           Data.Aeson.Lens (AsValue, key, _Value)
+import           Data.Maybe      (fromMaybe)
+import           Data.Text       (Text)
+
+{- |
+From given JSON and selectors returns typed field. If input JSON is not valid or selected field is not found then error is thrown.
+If you need more safe way use '(|-?)' instead. Examples:
+
+-- >>> "5" |-- [] :: Int
+-- 5
+-- >>> "5" |-- [] :: Float
+-- 5.0
+-- >>> "5" |-- [] :: String
+-- *** Exception: Data.Aeson.Picker: could not pick field with path: []
+--
+-- >>> :set -XOverloadedStrings
+-- >>> "{\"a\": 5}" |-- ["a"] :: Int
+-- 5
+-- >>> "{\"a\": 5}" |-- ["b"] :: Int
+-- *** Exception: Data.Aeson.Picker: could not pick field with path: ["b"]
+-- >>> "{\"outer\": {\"inner\": [1,2,3]}}" |-- ["outer", "inner"] :: [Int]
+-- [1,2,3]
+-- >>> {\"outer\": {\"inner\": [1,2,3]}}" |-- ["outer", "inner"] :: [Double]
+-- [1.0,2.0,3.0]
+-- >>> "{a: 5}" |-- ["a"] :: Int
+-- *** Exception: Data.Aeson.Picker: input json is not valid
+-}
+infix 5 |--
+(|--) :: (AsValue t, FromJSON a) => t -> [Text] -> a
+json |-- selectors = fromMaybe (error $ "Data.Aeson.Picker: could not pick field with path: " ++ show selectors) $ json |-? selectors
+
+{- |
+From given JSON and selectors returns typed field inside 'Maybe'. If input JSON is not valid then error is thrown.
+Examples:
+
+-- >>> "5" |-? [] :: Maybe Int
+-- Just 5
+-- >>> "5" |-? [] :: Maybe String
+-- Nothing
+-- >>> "{\"a\": 5}" |-? ["a"] :: Maybe Int
+-- Just 5
+-- >>> "{a: 5}" |-? ["a"] :: Maybe Int
+-- *** Exception: Data.Aeson.Picker: input json is not valid
+-}
+infix 5 |-?
+(|-?) :: (AsValue t, FromJSON a) => t -> [Text] -> Maybe a
+json |-? selectors = let validJSON = checkValidity json
+                     in pick validJSON selectors >>= convert
+
+-- | Checks validity for JSON format. Throws error if it is not valid.
+checkValidity :: AsValue t => t -> t
+checkValidity json = fromMaybe (error "Data.Aeson.Picker: input json is not valid") (json ^? _Value) `seq` json
+
+-- | Picks from given JSON selected field
+pick :: AsValue t => t -> [Text] -> Maybe Value
+pick json []        = json ^? _Value
+pick json selectors = json ^? genGetter selectors
+
+-- | Converts from 'Value'
+convert :: FromJSON a => Value -> Maybe a
+convert value = case fromJSON value of
+  Success r -> Just r
+  Error _   -> Nothing
+
+-- | Generates getter from given selectors
+genGetter :: AsValue t => [Text] -> Traversal' t Value
+genGetter []     = error "Data.Aeson.Picker.Internal.Functions.genGetter: this should not be happened"
+genGetter [x]    = key x
+genGetter (x:xs) = key x . genGetter xs 
diff --git a/src/Data/Aeson/Picker/Internal/Functions.hs b/src/Data/Aeson/Picker/Internal/Functions.hs
deleted file mode 100644
--- a/src/Data/Aeson/Picker/Internal/Functions.hs
+++ /dev/null
@@ -1,38 +0,0 @@
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE RankNTypes        #-}
-
-module Data.Aeson.Picker.Internal.Functions
-  ( (|--)
-  , (|-?)
-  ) where
-
-import           Control.Lens      (Traversal', (^?))
-import           Data.Aeson        (FromJSON (..), Result (..), Value, fromJSON)
-import           Data.Aeson.Lens   
-import           Data.Maybe        (fromJust)
-import           Data.Text         (Text)
-
-infix 5 |--
-(|--) :: (AsValue t, FromJSON a) => t -> [Text] -> a
-json |-- []        = getFromValue . fromJust $ json ^? _Value
-json |-- selectors = getFromValue . fromJust $ json ^? genGetter selectors
-
-infix 5 |-?
-(|-?) :: (AsValue t, FromJSON a) => t -> [Text] -> Maybe a
-json |-? []        = (json ^? _Value)              >>= getFromValueM
-json |-? selectors = (json ^? genGetter selectors) >>= getFromValueM
-
-genGetter :: AsValue t => [Text] -> Traversal' t Value
-genGetter []     = error "selector should has at least one field"
-genGetter [x]    = key x
-genGetter (x:xs) = key x . genGetter xs
-
-getFromValue :: FromJSON a => Value -> a
-getFromValue value = case fromJSON value of
-  Success r -> r
-  Error e   -> error e
-
-getFromValueM :: FromJSON a => Value -> Maybe a
-getFromValueM value = case fromJSON value of
-  Success r -> Just r
-  Error e   -> Nothing
