<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def bar(x_fn, y_fn, *, options={}, **interact_params):
 """ Generates an interactive bar chart that allows users to change the parameters of the inputs x_fn and y_fn. Args: x_fn (Array | (*args -> Array str | Array int | Array float)):
 If array, uses array values for categories of bar chart. If function, must take parameters to interact with and return an array of strings or numbers. These will become the categories on the x-axis of the bar chart. y_fn (Array | (Array, *args -> Array int | Array float)):
 If array, uses array values for heights of bars. If function, must take in the output of x_fn as its first parameter and optionally other parameters to interact with. Must return an array of numbers. These will become the heights of the bars on the y-axis. Kwargs: {options} interact_params (dict):
 Keyword arguments in the same format as `ipywidgets.interact`. One argument is required for each argument of both `x_fn` and `y_fn`. If `x_fn` and `y_fn` have conflicting parameter names, prefix the corresponding kwargs with `x__` and `y__`. Returns: VBox with two children: the interactive controls and the figure. """

    params = {
        'marks': [{
            'x': _array_or_placeholder(x_fn, PLACEHOLDER_RANGE),
            'y': _array_or_placeholder(y_fn)
        }]
    }
    fig = options.get('_fig', False) or _create_fig(
        x_sc=bq.OrdinalScale, options=options
    )
    [bar] = _create_marks(
        fig=fig, marks=[bq.Bars], options=options, params=params
    )
    _add_marks(fig, [bar])

    def wrapped(**interact_params):
        x_data = util.maybe_call(x_fn, interact_params, prefix='x')
        bar.x = x_data

        y_bound = util.maybe_curry(y_fn, x_data)
        bar.y = util.maybe_call(y_bound, interact_params, prefix='y')

    controls = widgets.interactive(wrapped, **interact_params)

    return widgets.VBox([controls, fig])