bartavelle / language-puppet

A library to work with Puppet manifests, test them and eventually replace everything ruby.
BSD 3-Clause "New" or "Revised" License
51 stars 8 forks source link

stdlib :: join_keys_to_values #174

Closed jfroche closed 8 years ago

jfroche commented 8 years ago

https://github.com/danzilio/puppet-letsencrypt fails now on this error:

Unknown function: join_keys_to_values

I thought it would be easy but I don't know enough haskell yet. I tried (based on the any2array function):

 join_keys_to_values :: [PValue] -> InterpreterMonad PValue
 join_keys_to_values [PHash h, sep] = return (PArray lst)
     where lst = V.fromList $ map arraypair $ HM.toList h
           arraypair (k, v) = T.intercalate s [k, v]
           s = resolvePValueString sep

https://forge.puppetlabs.com/puppetlabs/stdlib#join_keys_to_values ruby code: https://github.com/puppetlabs/puppetlabs-stdlib/blob/master/lib/puppet/parser/functions/join_keys_to_values.rb

PierreR commented 8 years ago

This is ugly as hell but it works I would think:

joinKeysToValues :: [PValue] -> InterpreterMonad PValue
joinKeysToValues [PHash h, PString separator] = do
  let foldfunc acc k v =
        (PString <$> (mappend (k <> separator) <$> resolvePValueString v)) : acc
      xs = sequence $ V.fromList $ reverse $ HM.foldlWithKey' foldfunc [] h
  PArray <$> xs
joinKeysToValues _ = throwPosError "join_keys_to_values(): expects 2 arguments, an hash and a string"

I will try to clean it up a bit but please fire your suggestion already ;-) I guess there is a cleaner way to write the fold function.

bartavelle commented 8 years ago

How should the keys be sorted ?

bartavelle commented 8 years ago

How should the keys be sorted ?

PierreR commented 8 years ago

My understanding is that you keep the original order (from the PHash input).

PierreR commented 8 years ago

I think this shot is better because we should be able to 'show' all PValue:

joinKeysToValues :: [PValue] -> InterpreterMonad PValue
joinKeysToValues [PHash h, PString separator] = do
  let
    joinKeysToValue k s v = PString $ k <> s <> T.pack (show v)
    xs = V.fromList $ HM.foldrWithKey (\k v s -> joinKeysToValue k separator v : s) [] h
  return $ PArray xs
joinKeysToValues _ = throwPosError "join_keys_to_values(): expects 2 arguments, an hash and a string"
PierreR commented 8 years ago

But we probably need to use something like a "compact pretty (no colors ...) instead of show for PValue

bartavelle commented 8 years ago

I am not sure all values should be allowed ... anyway, why an explicit foldr instead of something like :

fmap (PArray . V.fromList) $ forM (itoList h) $ \(k,v) -> ...
bartavelle commented 8 years ago

If the original ordering is to be kept, it means that a PHash should be stored as a [(Text, PValue)] ...

bartavelle commented 8 years ago

Ordering is not to be preserved according to the puppetlabs test suite.

PierreR commented 8 years ago

itoList is quite handy indeed. Thanks !