Switch expression function
There is quite a bit of code duplication due to a few nearly identical functions being needed.
  


This is probably the biggest issue and the one I'll be addressing here.

The two schwitch functions have identical bodies, this is a major code smell. The only difference between the two is the generic constraints on T and the type T is wrapped up in (Array and Caze repectively). You don't actually care that Tconforms to ForwardIndexType in the schwitch function and the only way I was using both Caze and Array was by calling contains on them (with identical signatures). This clearly calls for a protocol. And I didn't even need to declare one myself. the contains function I was using is declared in SequenceType, a protocol both Array and Range conform to. So here's what the new (and only) schwitch function will look like:

func schwitch&lt;S: SequenceType, R where S.Generator.Element: Equatable&gt;(value: S.Generator.Element, _ cases: (S, () -&gt; R)..., @autoclosure def: () -&gt; R) -&gt; R {
    for (vals, f) in cases {
        if vals.contains(value) {
            return f()
        }
    }
    return def()
}


You will notice that function is now missing a rethrows, the swift compiler hangs up on that due to a bug.

This also allowed me to get rid of the Caze enum and only have two caze functions, one that takes any amount of values and one that takes a range:

func caze&lt;T: Equatable, R&gt;(vals: T..., @autoclosure(escaping) ret f: () -&gt; R) -&gt; (AnySequence&lt;T&gt;, () -&gt; R) {
    return (AnySequence(vals), f)
}

func caze&lt;T, R where T: Equatable, T: ForwardIndexType&gt;(range: Range&lt;T&gt;, @autoclosure(escaping) ret f: () -&gt; R) -&gt; (AnySequence&lt;T&gt;, () -&gt; R) {
    return (AnySequence(range), f)
}


I've made both functions return an AnySequence&lt;T&gt; instead of more concrete type, I think that makes sense, considering how the results are used, but it's really up to you if you maybe want to return Array&lt;T&gt; and Range&lt;T&gt; instead.

I can still use my function exactly as I did before.