[swift-evolution] Feasibility of "T1 & ¬T2"

Douglas Gregor dgregor at apple.com
Wed Nov 29 23:13:09 CST 2017



> On Nov 29, 2017, at 7:27 PM, Dave DeLong via swift-evolution <swift-evolution at swift.org> wrote:
> 
> Hi SE,
> 
> I’m pondering some esoteric type stuff as I’m sketching out an improved date/time library (https://github.com/davedelong/Chronology <https://github.com/davedelong/Chronology>), and I’m wondering two things:
> 
> 1️⃣ Is there a way to express a type that does *not* conform to a protocol? 
> 
> For example, let’s say I have three protocols:
> 
> protocol YearHaving { var year: Int }
> protocol MonthHaving { var month: Int }
> protocol DayHaving { var day: Int }
> typealias DateHaving = YearHaving & MonthHaving & DayHaving
> 
> Now, I want to allow for some adjustments to values that have these types:
> 
> extension DayHaving {
>     func removingDay() → Self & ¬DayHaving // whatever type “self” is, except it does not conform to “DayHaving”, because you just removed the day value
> }
> 
> Is this possible?

There is no way to express this.

> 
> 2️⃣ If this is not possible, would it be hard to add something like this in?

It would not be hard, although do note that it can only check “there is no conformance of the type to the protocol visible from this module”; a conformance might be present in some other module, or might be loaded dynamically later on. It can also be “hidden” from the static type system:

func f<T>(_: T) where ¬DayHaving { }
struct X { }
f(X()) // okay
struct Y : DayHaving { }
f(Y()) // error: Y conforms to DayHaving but shouldn’t

func g<T>(_ t: T) { f(t) } // succeeds, because T is not known to conform to DayHaving
g(X()) // okay, as expected
g(Y()) // okay, but surprising

	- Doug


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20171129/df82ae0c/attachment.html>


More information about the swift-evolution mailing list