Search code examples
swiftxcodefunctional-programmingmemoizationchess

How to make a generic memoization function with multiple arguments in Swift?


I am making a chess engine (which heavily relies on functional programming) and it requires memoization at every step to avoid re-computation. I read this article which provided a generic function for memoization:

http://simon-fortelny.com/2017/07/04/GenericMemoization/

Code:

    func memoize<T: Hashable, U>(function: @escaping (T) -> U) ->  (T) -> U {
        var cache : [T: U] = [:]
        func memoWrapper(input: T) -> U {
            if let cacheValue = cache[input] {
                return cacheValue
            }
            let newVal = function(input)
            cache[input] = newVal
            return newVal
        }
        return memoWrapper
    }

Now I want to extend that function to accept multiple input parameters. I tried using variadic arguments like this:

    func memoize<T: Hashable, U>(function: @escaping (T...) -> U) ->  (T...) -> U {
        var cache : [[T]: U] = [:]
        func memoWrapper(input: T...) -> U {
            if let cacheValue = cache[input] {
                return cacheValue
            }
            let newVal = function(input)
            cache[input] = newVal
            return newVal
        }
        return memoWrapper
    }

But I'm getting 2 errors:

  1. Type of expression is ambiguous without more context
  2. Cannot pass array of type '[T]' as variadic arguments of type 'T'

screenshot

Any idea what I'm doing wrong and how to make it support multiple arguments?


Solution

  • Thanks for the comments guys. I ended up figuring it out (thanks to this answer)

    I created a struct to pass to the function instead of multiple parameters as variadic arguments.

    struct PairState<T: Hashable, U: Hashable>: Hashable {
        let first: T
        let second: U
    }