diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,11 @@
+language-puppet (1.3.20) UNRELEASED; urgency=medium
+
+  * Add `length` as an alias to `size`.
+  * Add the `unique` stdlib function.
+  * Fix a small problem with `postgresql_acls_to_resources_hash`
+
+ -- Simon Marechal <simon.marechal@edf.fr>  Tue, 24 Jul 2018 17:47:07 +0200
+
 language-puppet (1.3.19.1) xenial; urgency=medium
 
   * Relaxed yaml version bounds
diff --git a/language-puppet.cabal b/language-puppet.cabal
--- a/language-puppet.cabal
+++ b/language-puppet.cabal
@@ -2,7 +2,7 @@
 -- documentation, see http://haskell.org/cabal/users-guide/
 
 name:                language-puppet
-version:             1.3.19.1
+version:             1.3.20
 synopsis:            Tools to parse and evaluate the Puppet DSL.
 description:         This is a set of tools that is supposed to fill all your Puppet needs : syntax checks, catalog compilation, PuppetDB queries, simulation of complex interactions between nodes, Puppet master replacement, and more !
 homepage:            http://lpuppet.banquise.net/
@@ -137,7 +137,7 @@
                      , unix                 >= 2.7  && < 2.8
                      , unordered-containers == 0.2.*
                      , vector               >= 0.10
-                     , yaml                 >= 0.8.8   && < 0.10
+                     , yaml                 >= 0.8.31   && < 0.10
 Test-Suite spec
   hs-source-dirs: tests
   type:           exitcode-stdio-1.0
diff --git a/src/Puppet/Runner/Preferences.hs b/src/Puppet/Runner/Preferences.hs
--- a/src/Puppet/Runner/Preferences.hs
+++ b/src/Puppet/Runner/Preferences.hs
@@ -99,7 +99,7 @@
         testdir = dirpaths ^. testPath
         hierafile = basedir <> "/hiera.yaml"
         defaultfile = testdir <> "/defaults.yaml"
-    defaults <- ifM (Directory.doesFileExist defaultfile) (either (const Nothing) Just <$> Yaml.decodeFileEither defaultfile) (pure Nothing)
+    defaults <- ifM (Directory.doesFileExist defaultfile) (Yaml.decodeFileThrow defaultfile) (pure Nothing)
     hieradir <- ifM (Directory.doesFileExist hierafile) (pure $ Just hierafile) (pure Nothing)
     loadedtypes <- loadedTypes modulesdir
     labsFunctions <- Puppetlabs.extFunctions modulesdir
diff --git a/src/Puppet/Runner/Puppetlabs.hs b/src/Puppet/Runner/Puppetlabs.hs
--- a/src/Puppet/Runner/Puppetlabs.hs
+++ b/src/Puppet/Runner/Puppetlabs.hs
@@ -5,6 +5,7 @@
 
 import           Crypto.Hash         as Crypto
 import           Data.ByteString     (ByteString)
+import           Data.Char           (isDigit)
 import           Data.Foldable       (foldlM)
 import qualified Data.HashMap.Strict as HM
 import           Data.Scientific     as Sci
@@ -84,9 +85,7 @@
 -- For instance 'auth_option' is currently not implemented.
 -- Please add cases as needed.
 pgAclsToHash :: MonadThrowPos m => [PValue] -> m PValue
-pgAclsToHash [PArray as, PString ident, PNumber offset] = do
-  x <- aclsToHash as ident offset
-  return $ PHash x
+pgAclsToHash [PArray as, PString ident, PNumber offset] = PHash <$> aclsToHash as ident offset
 pgAclsToHash _ = throwPosError "expects 3 arguments; one array one string and one number"
 
 aclsToHash :: MonadThrowPos m  => Vector PValue -> Text -> Scientific -> m (Container PValue)
@@ -101,14 +100,28 @@
     f _ _ pval = throwPosError $ "expect a string as acl but get" <+> pretty pval
 
 aclToHash :: (MonadThrowPos m) => [Text] -> Scientific -> m PValue
-aclToHash [typ, db, usr, addr, auth] order =
-  return $ PHash $ HM.fromList [ ("type", PString typ)
-                      , ("database", PString db )
-                      , ("user", PString usr)
-                      , ("order", PString (sformat (FMT.left 3 '0' %. scifmt Sci.Fixed (Just 0))  order))
-                      , ("address", PString addr)
-                      , ("auth_method", PString auth)
-                      ]
+aclToHash acl@(typ : db : usr : remaining) order = analyze
+  where
+    fin remn hs = return $ PHash $
+        if null remn
+          then hs
+          else HM.insert "auth_option" (PString (Text.unwords remn)) hs
+    analyze = case remaining of
+                method : remn | typ == "local" ->
+                  fin remn $ baseHash & at "auth_method" ?~ PString method
+                addr : msk : method : remn | Text.all isDigit msk ->
+                  fin remn $ baseHash & at "address" ?~ PString (Text.unwords [addr,msk])
+                                      & at "auth_method" ?~ PString method
+                addr : method : remn ->
+                  fin remn $ baseHash & at "address" ?~ PString addr
+                                      & at "auth_method" ?~ PString method
+                _ -> throwPosError $ "Unable to parse acl line" <+> squotes (ppline (Text.unwords acl))
+    baseHash = HM.fromList
+                  [ ("type", PString "local")
+                  , ("database", PString db )
+                  , ("user", PString usr)
+                  , ("order", PString (sformat (FMT.left 3 '0' %. scifmt Sci.Fixed (Just 0))  order))
+                  ]
 aclToHash acl _ = throwPosError $ "Unable to parse acl line" <+> squotes (ppline (Text.unwords acl))
 
 -- faked implementation, replace by the correct one if you need so.
diff --git a/src/Puppet/Runner/Stdlib.hs b/src/Puppet/Runner/Stdlib.hs
--- a/src/Puppet/Runner/Stdlib.hs
+++ b/src/Puppet/Runner/Stdlib.hs
@@ -13,6 +13,7 @@
 import qualified Data.List.Split                  as List (chunksOf)
 import qualified Data.Scientific                  as Scientific
 import qualified Data.Text                        as Text
+import           Data.Text.Lens                   (unpacked)
 import qualified Data.Vector                      as V
 import           Data.Vector.Lens                 (toVectorOf)
 import qualified Text.Regex.PCRE.ByteString.Utils as Regex
@@ -79,6 +80,7 @@
                               , ("join", puppetJoin)
                               , ("join_keys_to_values", joinKeysToValues)
                               , singleArgument "keys" keys
+                              , singleArgument "length" size
                               -- load_module_metadata
                               -- loadyaml
                               , ("lstrip", stringArrayFunction Text.stripStart)
@@ -115,7 +117,7 @@
                               -- type3x
                               -- type
                               -- union
-                              -- unique
+                              , singleArgument "unique" unique
                               -- unix2dos
                               , ("upcase", stringArrayFunction Text.toUpper)
                               -- uriescape
@@ -424,12 +426,17 @@
 size (PString s) = return (_Integer # fromIntegral (Text.length s))
 size x = throwPosError ("size(): Expects a hash, and array or a string, not" <+> pretty x)
 
+unique :: PValue -> InterpreterMonad PValue
+unique (PString s) = return $ PString (s & unpacked %~ List.nub)
+unique (PArray v) = return $ PArray (V.fromList (List.nub (V.toList v))) -- :(
+unique x = throwPosError ("unique(): Expects an array or a string, not" <+> pretty x)
+
 sort :: PValue -> InterpreterMonad PValue
 sort (PArray s) =
   let lst = V.toList s
       msort :: Ord a => Prism' PValue a -> Maybe PValue
       msort prsm = PArray . V.fromList . map (review prsm) . List.sort <$> mapM (preview prsm) lst
-  in  case (msort _PString <|> msort _PNumber) of
+  in  case msort _PString <|> msort _PNumber of
         Just x -> return x
         _ -> throwPosError "sort(): only homogeneous arrays of numbers or strings are allowed"
 sort x = throwPosError ("sort(): Expect to sort an array, not" <+> pretty x)
