diff --git a/aeson-value-parser.cabal b/aeson-value-parser.cabal
--- a/aeson-value-parser.cabal
+++ b/aeson-value-parser.cabal
@@ -1,5 +1,5 @@
 name: aeson-value-parser
-version: 0.14.2
+version: 0.14.3
 synopsis: An API for parsing "aeson" JSON tree into Haskell types
 description:
 category: Data, JSON, Parsing
diff --git a/library/Aeson/ValueParser.hs b/library/Aeson/ValueParser.hs
--- a/library/Aeson/ValueParser.hs
+++ b/library/Aeson/ValueParser.hs
@@ -22,11 +22,15 @@
   oneOfFields,
   fieldOr,
   oneOfFieldsOr,
+  possibleField,
+  oneOfPossibleFields,
   fieldMap,
   foldlFields,
   -- * Array parsers
   Array,
   element,
+  elementOr,
+  possibleElement,
   elementVector,
   foldlElements,
   foldrElements,
@@ -177,16 +181,42 @@
 oneOfFields :: [Text] -> Value a -> Object a
 oneOfFields keys valueParser = asum (fmap (flip field valueParser) keys)
 
-fieldOr :: Text -> Value a -> Object a -> Object a
-fieldOr name parser alt =
-  join $ mplus
-    (field name (catchError (fmap pure parser) (pure . throwError . Error.named name)))
-    (pure alt)
+{-| Applies the value parser to the existing field, propagating its errors accordingly.
+    Only if the field does not exist, it executes /Alternative branch/.
+    IOW, it won't execute /Alternative branch/ if /Field parser/ fails.
+    This is what distinguishes @fieldOr name parser@ from the seemingly same @mplus (field name parser)@ -}
+fieldOr :: Text {-^ Field name -} -> Value a {-^ Field parser -} -> Object a {-^ Alternative branch -} -> Object a
+fieldOr name (Value fieldParser) alt = join $ Object $ ReaderT $ \ object -> except $ case HashMap.lookup name object of
+  Just value -> case runExcept (runReaderT fieldParser value) of
+    Right parsedValue -> Right (return parsedValue)
+    Left error -> Left (Error.named name error)
+  Nothing -> Right alt
 
+{-| Same as `fieldOr`,
+    with the only difference that it enumerates the provided list of field names
+    parsing the first existing one. -}
 oneOfFieldsOr :: [Text] -> Value a -> Object a -> Object a
 oneOfFieldsOr names valueParser objectParser =
   foldr (\ name -> fieldOr name valueParser) objectParser names
 
+{-| Applies the value parser to the existing field, propagating its errors accordingly, but
+    unlike `field` it doesn't fail if the field does not exist.
+    The `Maybe` wrapper is there to cover such a case. -}
+{-# INLINE possibleField #-}
+possibleField :: Text -> Value a -> Object (Maybe a)
+possibleField key (Value effect) = Object $ ReaderT $ \ object -> except $ case HashMap.lookup key object of
+  Just value -> case runExcept (runReaderT effect value) of
+    Right parsedValue -> Right (Just parsedValue)
+    Left error -> Left (Error.named key error)
+  Nothing -> Right Nothing
+
+{-| Same as `possibleField`,
+    with the only difference that it enumerates the provided list of field names
+    parsing the first existing one. -}
+{-# INLINE oneOfPossibleFields #-}
+oneOfPossibleFields :: [Text] -> Value a -> Object (Maybe a)
+oneOfPossibleFields keys valueParser = oneOfFieldsOr keys (fmap Just valueParser) (pure Nothing)
+
 {-# INLINE fieldMap #-}
 fieldMap :: Value a -> Object (HashMap Text a)
 fieldMap fieldParser = Object $ ReaderT $ except . HashMap.traverseWithKey mapping where
@@ -223,6 +253,22 @@
     Right result -> Right result
     Left error -> Left (Error.indexed index error)
   Nothing -> Left (Error.Error (pure (fromString (show index))) "Array contains no element by this index")
+
+{-# INLINE elementOr #-}
+elementOr :: Int -> Value a -> Array a -> Array a
+elementOr index elementParser alt = join $ Array $ ReaderT $ \ array -> except $ case array Vector.!? index of
+  Just element -> case run elementParser element of
+    Right result -> Right (return result)
+    Left error -> Left (Error.indexed index error)
+  Nothing -> Right alt
+
+{-# INLINE possibleElement #-}
+possibleElement :: Int -> Value a -> Array (Maybe a)
+possibleElement index elementParser = Array $ ReaderT $ \ array -> except $ case array Vector.!? index of
+  Just element -> case run elementParser element of
+    Right result -> Right (Just result)
+    Left error -> Left (Error.indexed index error)
+  Nothing -> Right Nothing
 
 {-# INLINE elementVector #-}
 elementVector :: Value a -> Array (Vector a)
diff --git a/library/Aeson/ValueParser/Error.hs b/library/Aeson/ValueParser/Error.hs
--- a/library/Aeson/ValueParser/Error.hs
+++ b/library/Aeson/ValueParser/Error.hs
@@ -7,7 +7,7 @@
 data Error = Error [Text] {-^ Path -} Text {-^ Message -}
 
 instance Semigroup Error where
-  (<>) a _ = a
+  (<>) _ b = b
 
 instance Monoid Error where
   mempty = Error [] ""
