docs: def merge(*args, **kwargs):
      '''
      merge(...) lazily collapses all arguments, which must be python Mapping objects of some kind,
        into a single mapping from left-to-right. The mapping that is returned is a lazy persistent
        object that does not request the value of a key from any of the maps provided until they are
        requested of it; in this fashion it preserves the laziness of immutable map objects that are
        passed to it. Arguments may be mappings or lists/tuples of mappings.
  
      If all of the arguments passed to merge are pimms itables with the same row_count, then an
      itable object is returned instead of a lazy map.
  
      The following options are accepted:
      * choose (default None) specifies a function that chooses from which map, of those maps given
        to merge, the value should be drawn when keys overlap. The function is always passed two
        arguments: the key for which the conflict occurs and a list of maps containing that key; it
        should return the value to which the key should be mapped. The default uses the first map.
      '''
      from .table import (is_itable, ITable)
      # figure out the choose-fn
      choose_fn = None
      if 'choose' in kwargs:
          choose_fn = kwargs['choose']
      if len(kwargs) > 1 or (len(kwargs) > 0 and 'choose' not in kwargs):
          raise ValueError('Unidentified options given to merge: %s' (kwargs.keys(),))
      # collect the maps...
      maps = flatten_maps(*args)
      if len(maps) == 0: return ps.m()
      elif len(maps) == 1: return maps[0]
      coll = collect(maps)
      if choose_fn is None: choose_fn = _choose_last
      def curry_choice(k, args): return lambda:choose_fn(k, args)
      resmap = lazy_map({k:curry_choice(k, v) for (k,v) in six.iteritems(coll)})
      # if they're all itables of the same size, return an itable
      if is_itable(maps[0]):
          n = maps[0].row_count
          if all(is_itable(m) and m.row_count == n for m in maps):
              return ITable(resmap, n)
      # otherwise return the lazy map
      return resmap