0

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?

Adnan Zahid
  • 573
  • 1
  • 10
  • 38
  • 2
    The second error is easy to understand. You can't perpetuate a variadic. It's that simple. There is no variadic type; the only place a variadic can be used is in declaring a function parameter. The _actual_ parameter arrives into the function as an array, and it cannot be turned back into a variadic in order to make another call ("splatting", a language feature that Swift is missing). – matt Sep 24 '20 at 22:42
  • 1
    Do you really mean `T...` here? That means that all the parameter types have to be the same, not a function that takes an arbitrary number of parameters of different types. – Rob Napier Sep 25 '20 at 00:49
  • Thanks for the comments @matt and Rob Napier, it helped me figure out what I was doing wrong – Adnan Zahid Sep 25 '20 at 14:04

1 Answers1

1

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
}
Adnan Zahid
  • 573
  • 1
  • 10
  • 38