[swift-evolution] 'T != Type' in where clause

Rex Fenley rex at remind101.com
Tue Feb 28 14:04:49 CST 2017


Here's a simplified section of code I'm writing for mapping some data from
over the wire


public protocol Transform {
    // a bunch of stuff
}

public protocol Key {
    // a bunch of stuff
}

extension String: Key { /* conforming stuff */ }

public protocol JSONType { }
extension Int: JSONType { }

public enum Bind<T>: Key {
    case transform(Key, T)
    // a few more cases, every case must have a Key, we forward all of
Key's methods through each case.
}

public func map<T: JSONType>(field: inout T, binding: Key) {
    print(field)
}

public func map<T, U: Transform>(field: inout T, binding: Bind<U>) {
    print(field)
}

class SpecialTransform: Transform { }

var s = Int()
// Ambiguity here.
map(field: &s, binding: Bind.transform("data.stuff", SpecialTransform()))


Probably would be better to make `Bind` not conform to `Key`, would just
require a bunch of refactoring in places where I've used the two
interchangeably. However, one of the benefits of having `Bind: Key` is that
it enforces that every additional case has a `Key` which will always be
true for this data structure.

I was thinking the first `map` would change  to

public func map<T: JSONType, K: Key>(field: inout T, binding: K)


But to have `K != Bind<Any>`, Bind<Any> would have to be the super type of
all other Bind<T>s which currently isn't true anyway so this is kind of
dead on arrival.

Interestingly though, when I change the signature to

public func map<T: JSONType, K: Key>(field: inout T, binding: K)


Instead of "Ambiguous use of...", the program compiles and calls this
method instead of the overload with Bind<U>. Not only is this not the
function I want called, but this seems like inconsistent behavior with the
type checker (compiling vs throwing an "Ambiguous use of..." error).
Should I report a bug here or am I missing something?

On Tue, Feb 28, 2017 at 9:35 AM, Matthew Johnson <matthew at anandabits.com>
wrote:

>
> On Feb 28, 2017, at 11:33 AM, Joe Groff <jgroff at apple.com> wrote:
>
>
> On Feb 28, 2017, at 9:23 AM, Matthew Johnson <matthew at anandabits.com>
> wrote:
>
>
> On Feb 28, 2017, at 11:04 AM, Joe Groff via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>
> On Feb 27, 2017, at 4:34 PM, Rex Fenley via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> I often find myself running into situations where I'll receive "Ambiguous
> use of..." for overloaded functions or operators. In every case these
> situations would be easily solved if I could specify "Generic !=
> CertainType" in the where clause of one of the overloads so I can
> disambiguate the cases. Could this be added to language?
>
>
> Do you have a concrete example where you need this? It'd be good to know
> whether the types are ambiguous due to type checker bugs, or whether
> there's a principle by which they could be naturally ordered. Instead of
> overloading, can you do the type test via `if !(x is CertainType)` within a
> single implementation?
>
>
> The best use case I can think of is if we had enum cases where the
> associated value is a subtype of the enum:
>
> enum Result<T, E> where E: Error, T != E {
>   case some(T) -> T
>   case error(E) -> E
> }
>
>
> I don't think that's a good design for that type. I can see the desire for
> a subtype relationship between T and Result<T, E>, but no good reason for
> the error to also be a subtype. That != constraint would have to be
> propagated through anything using `Result<T, E>` as well.
>
>
> Ok, just change it to a fully generic Either type then.  I’m not arguing
> for or against this constraint, just pointing out a use case that is
> enabled by it.  It’s reasonable to argue that we don’t want to support this
> use case.
>
>
> -Joe
>
>
>


-- 

Rex Fenley  |  IOS DEVELOPER

Remind.com <https://www.remind.com/> |  BLOG <http://blog.remind.com/>
 |  FOLLOW
US <https://twitter.com/remindhq>  |  LIKE US
<https://www.facebook.com/remindhq>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170228/cd9c4f77/attachment.html>


More information about the swift-evolution mailing list