Currying a proc with keyword arguments in Ruby

后端 未结 4 973
刺人心
刺人心 2021-01-17 22:44

Say I have a generic Proc, Lambda or method which takes an optional second argument:

pow = -> (base, exp: 2) { base         


        
4条回答
  •  梦毁少年i
    2021-01-17 23:24

    You could build your own keyword-flavored curry method that collects keyword arguments until the required parameters are present. Something like:

    def kw_curry(method)
      -> (**kw_args) {
        required = method.parameters.select { |type, _| type == :keyreq }
        if required.all? { |_, name| kw_args.has_key?(name) }
          method.call(**kw_args)
        else
          -> (**other_kw_args) { kw_curry(method)[**kw_args, **other_kw_args] }
        end
      }
    end
    
    def foo(a:, b:, c: nil)
      { a: a, b: b, c: c }
    end
    
    proc = kw_curry(method(:foo))
    proc[a: 1]              #=> #
    proc[b: 1]              #=> #
    proc[a: 1, b: 2]        #=> {:a=>1, :b=>2, :c=>nil}
    proc[b: 2][a: 1]        #=> {:a=>1, :b=>2, :c=>nil}
    proc[a: 1, c: 3][b: 2]  #=> {:a=>1, :b=>2, :c=>3}
    

    The example above is limited to keyword arguments only, but you can certainly extend it to support both, keyword arguments and positional arguments.

提交回复
热议问题