diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 # salak
 
-[![Hackage](https://img.shields.io/badge/hackage-v0.1.5-orange.svg)](https://hackage.haskell.org/package/salak)
+[![Hackage](https://img.shields.io/badge/hackage-v0.1.6-orange.svg)](https://hackage.haskell.org/package/salak)
 [![Build Status](https://travis-ci.org/leptonyu/salak.svg?branch=master)](https://travis-ci.org/leptonyu/salak)
 
 
diff --git a/salak.cabal b/salak.cabal
--- a/salak.cabal
+++ b/salak.cabal
@@ -1,6 +1,6 @@
 cabal-version: 1.12
 name: salak
-version: 0.1.5
+version: 0.1.6
 license: BSD3
 license-file: LICENSE
 copyright: (c) 2018 Daniel YU
@@ -26,6 +26,7 @@
         Data.Salak.CommandLine
         Data.Salak.Aeson
         Data.Salak.Yaml
+        Data.Salak.Operation
     default-language: Haskell2010
     ghc-options: -Wall -Wcompat -Wincomplete-record-updates
                  -Wincomplete-uni-patterns -Wredundant-constraints -fno-warn-orphans
@@ -50,6 +51,7 @@
         Data.Salak.Aeson
         Data.Salak.CommandLine
         Data.Salak.Environment
+        Data.Salak.Operation
         Data.Salak.Types
         Data.Salak.Yaml
         Paths_salak
diff --git a/src/Data/Salak.hs b/src/Data/Salak.hs
--- a/src/Data/Salak.hs
+++ b/src/Data/Salak.hs
@@ -39,12 +39,15 @@
   , makePropertiesFromJson
   , makePropertiesFromYaml
   , FileName
+  -- * Operations
+  , module Data.Salak.Operation
   ) where
 
 import           Data.Maybe
 import           Data.Salak.Aeson
 import           Data.Salak.CommandLine
 import           Data.Salak.Environment
+import           Data.Salak.Operation
 import           Data.Salak.Types
 import           Data.Salak.Yaml
 import           Data.Text              (Text, unpack)
diff --git a/src/Data/Salak/Operation.hs b/src/Data/Salak/Operation.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Salak/Operation.hs
@@ -0,0 +1,28 @@
+module Data.Salak.Operation where
+
+import           Data.Salak.Types
+import           Data.Text        (Text, unpack)
+
+infixl 5 .?>
+(.?>) :: FromProperties a => Properties -> Text -> Return a
+(.?>) = flip lookup'
+
+infixl 5 .|=
+(.|=) :: Return a -> a -> a
+(.|=) (OK   a) _ = a
+(.|=) (Fail e) _ = error e
+(.|=) _        d = d
+
+infixl 5 .?=
+(.?=) :: Return a -> a -> Return a
+(.?=) a b = OK (a .|= b)
+
+infixl 5 .>>
+(.>>) :: FromProperties a => Properties -> Text -> a
+(.>>) p k = case p .?> k of
+  OK v   -> v
+  Empty  -> case fromProperties empty of
+    (OK   a) -> a
+    (Fail e) -> error e
+    _        -> error $ "Config " <> unpack k <> " not found"
+  Fail e -> error e
