title: Memoize with inputs that have commutative property?
body: <p>Imagine I have a function that simply sum up a list of numbers.</p>
  <pre class="lang-js prettyprint-override"><code>
  function add(...input) {
      return input.reduce((sum, num) =&gt; sum + num, 0)
  }
  </code></pre>
  <p>I want to memorize this function to avoid unnecessary computation so I wrote a higher order function <code>memoize</code></p>
  <pre class="lang-js prettyprint-override"><code>function memoize(fn, resolver) {
      const cache = new Map()
      
      return function(...args) {
          let key
          if(!resolver) key = args.join('')
          else key = resolver(...args)
          
          if (cache.has(key)) return cache.get(key)
          const val = fn(...args)
          cache.set(key, val)
  
          return val
      }
  }
  
  </code></pre>
  <p>now if we give <code>add</code> the same list of numbers, it will try to get the sum from the cache first before it computes the sum.</p>
  <p>However, the problem is that, the addition has associative property. E.g. <code>add(1,2,3)</code> and <code>add(2,1,3)</code> return the same value but the current implementation would treat them as different inputs so we have a cache miss but in reality it should be a cache hit.</p>
  <p>Was wondering if there is any ways we can implement a cache that takes this associative property into account?</p>