Strange Behavior With Closures


(bwm003@gmail.com) #1

Hi Everyone,
I was playing around in Xcode 7.3 with this code...

*/***

* * Represents a future value of type U, from a computation that has not
been done yet.*

* */*

*public struct Promise<T, U> {*

* var futureValue: T -> U*

* public func then<T,U,V>(closure: U -> V) -> Promise<T, V> {*

* return Promise<T, V>(futureValue: {*

* input in*

* let value = futureValue(input)*

* return closure(value)*

* })*

* }*

*}*

and came across the following error:

*error: cannot invoke value of type 'T -> U' with argument list '((T))'*

Can someone explain what is going on here? It looks like my closure should
be accepting a value of T, but for some reason the types aren't matching up.
Thanks, Blake


(Joe Groff) #2

You've shadowed Promise<T, U>'s generic type parameters T and U with new T and U type parameters on `then`. Remove those, and this should work:

public struct Promise<T, U> {
    var futureValue: T -> U
    
    public func then<V>(closure: U -> V) -> Promise<T, V> {
        return Promise<T, V>(futureValue: {
            input in
            let value = futureValue(input)
            return closure(value)
        })
    }
}

If you have time, we'd appreciate a bug report about producing a better diagnostic here. We should warn or error when generic parameters are shadowed like this.

-Joe

···

On May 4, 2016, at 6:19 PM, bwm003--- via swift-users <swift-users@swift.org> wrote:

Hi Everyone,
I was playing around in Xcode 7.3 with this code...

/**

* Represents a future value of type U, from a computation that has not been done yet.
*/
public struct Promise<T, U> {
    var futureValue: T -> U
    
    public func then<T,U,V>(closure: U -> V) -> Promise<T, V> {
        return Promise<T, V>(futureValue: {
            input in
            let value = futureValue(input)
            return closure(value)
        })
    }
}

and came across the following error:

error: cannot invoke value of type 'T -> U' with argument list '((T))'

Can someone explain what is going on here? It looks like my closure should be accepting a value of T, but for some reason the types aren't matching up.