I did some playing around in this answer, and have even raised a RADAR issue with Apple, asking for better documentation on the matter (Crickets chirping).
The question is this: How do String Intervals work?
If you look at line 367 in my playground, you'll see me messing with String Intervals.
I extracted the String stuff into a smaller playground:
// String Intervals
// These are odd. Looks like it is using the ASCII values. I should experiment with Unicode, and see where we go...
let aThroughFClosed:ClosedInterval<String> = "A"..."F"
let dThroughQClosed:ClosedInterval = "D"..."Q"
let mThroughSClosed:ClosedInterval = "M"..."S"
let tThroughWClosed:ClosedInterval = "T"..."W"
let whiskeyTangoFoxtrot1 = "QED"..."WTF" /* Not sure what will happen when I start working with this... */
let aThroughHHalfOpen:HalfOpenInterval<String> = "A"..<"H"
let dThroughRHalfOpen:HalfOpenInterval = "D"..<"R"
let mThroughTHalfOpen:HalfOpenInterval = "M"..<"T"
let tThroughXHalfOpen:HalfOpenInterval = "T"..<"X"
let whiskeyTangoFoxtrot2 = "QED"..<"WTF"
let clampedString1 = aThroughFClosed.clamp ( dThroughQClosed ) /* This represents "D"..."F" */
let clampedString2 = dThroughQClosed.clamp ( aThroughFClosed ) /* This represents "D"..."F" */
let clampedString3 = dThroughQClosed.clamp ( mThroughSClosed ) /* This represents "M"..."Q" */
let clampedString4 = dThroughQClosed.clamp ( tThroughWClosed ) /* This represents "Q"..."Q" */
let clampedString5 = aThroughFClosed.clamp ( tThroughWClosed ) /* This represents "F"..."F" */
let clampedString6 = aThroughHHalfOpen.clamp ( dThroughRHalfOpen ) /* This represents "D"..<"G" */
let clampedString7 = dThroughRHalfOpen.clamp ( aThroughHHalfOpen ) /* This represents "D"..<"H" */
let clampedString8 = dThroughRHalfOpen.clamp ( mThroughTHalfOpen ) /* This represents "M"..<"R" */
let clampedString9 = dThroughRHalfOpen.clamp ( tThroughXHalfOpen ) /* This represents "R"..<"R" */
let clampedString0 = aThroughHHalfOpen.clamp ( tThroughXHalfOpen ) /* This represents "H"..<"H" (Not exactly sure why) */
// 2.2.3: STRING INTERVALS
// String intervals are weird. Just sayin'...
// 2.2.3.1: STRING INTERVALS AS SWITCH TESTS
var testValue3:String = "B"
switch ( testValue3 )
{
case aThroughFClosed: /* This will catch it. */
println ( "In A...F." )
default:
println ( "In catchall." )
}
// Looks like the test is only on the first letter.
testValue3 = "Badz-Maru"
switch ( testValue3 )
{
case aThroughFClosed: /* This will catch it. */
println ( "In A...F." )
default:
println ( "In catchall." )
}
testValue3 = "\tBadz-Maru" /* If we add a tab character to the start of the string, then the first test will fail. */
switch ( testValue3 )
{
case aThroughFClosed:
println ( "In A...F." )
default: /* This will catch it. */
println ( "In catchall." )
}
// Now, we'll get really strange. Let's look at our multi-character intervals...
testValue3 = "W"
switch ( testValue3 )
{
case whiskeyTangoFoxtrot2: /* This catches it. */
println ( "WTF, dude?" )
default:
println ( "In catchall." )
}
testValue3 = "T"
switch ( testValue3 )
{
case whiskeyTangoFoxtrot2: /* This catches it. */
println ( "WTF, dude?" )
default:
println ( "In catchall." )
}
testValue3 = "F"
switch ( testValue3 )
{
case whiskeyTangoFoxtrot2:
println ( "WTF, dude?" )
default: /* However, in this case, it falls through to default. */
println ( "In catchall." )
}
testValue3 = "WT"
switch ( testValue3 )
{
case whiskeyTangoFoxtrot2: /* "WT" is caught. */
println ( "WTF, dude?" )
default:
println ( "In catchall." )
}
testValue3 = "WTF"
switch ( testValue3 )
{
case whiskeyTangoFoxtrot2:
println ( "WTF, dude?" )
default: /* "WTF" is not caught. */
println ( "In catchall." )
}
testValue3 = "QED"
switch ( testValue3 )
{
case whiskeyTangoFoxtrot2: /* "QED" is caught. */
println ( "WTF, dude?" )
default:
println ( "In catchall." )
}
testValue3 = "QTF"
switch ( testValue3 )
{
case whiskeyTangoFoxtrot2: /* "QTF" is caught. */
println ( "WTF, dude?" )
default:
println ( "In catchall." )
}
testValue3 = "QSF"
switch ( testValue3 )
{
case whiskeyTangoFoxtrot2: /* "QSF" is caught. */
println ( "WTF, dude?" )
default:
println ( "In catchall." )
}
testValue3 = "QAF"
switch ( testValue3 )
{
case whiskeyTangoFoxtrot2:
println ( "WTF, dude?" )
default: /* QAF falls through. */
println ( "In catchall." )
}
An interval on the guitar can be described as the distance from your root note, or the starting point, to another note on the fretboard. It's basically a musical distance between two notes and is represented by that specific distance.
To be exact, from low to high, standard guitar tuning is EADGBE—three intervals of a fourth (low E to A, A to D and D to G), followed by a major third (G to B), followed by one more fourth (B to the high E). The reason?
In music theory, an interval is a difference in pitch between two sounds. An interval may be described as horizontal, linear, or melodic if it refers to successively sounding tones, such as two adjacent pitches in a melody, and vertical or harmonic if it pertains to simultaneously sounding tones, such as in a chord.
As I understand it, ClosedInterval(lo, hi) represents all strings s such that
lo <= s <= hi
and HalfOpenInterval(lo, hi) represents all strings s such that
lo <= s < hi
where <= and < are determined by the lexicographic ordering of the Strings,
i.e. be comparing the characters one by one, until a difference is found.
For example "QED" < "T" < "WTF" because Q < T < W, but "F" < "QED" because
F < Q. Therefore
HalfOpenInterval("QED" , "WTF").contains("T") == true
HalfOpenInterval("QED" , "WTF").contains("F") == false
And "QED" < "QSF" because Q == Q and E < S, but "QAF" < "QED" because Q == Q and A < E. Therefore
HalfOpenInterval("QED" , "WTF").contains("QSF") == true
HalfOpenInterval("QED" , "WTF").contains("QAF") == false
That should explain all your test results.
Finally,
let clampedString0 = aThroughHHalfOpen.clamp ( tThroughXHalfOpen )
is an empty interval because "A"..<"H" and "T"..<"X" have no points in common.
An empty interval can be represented by HalfOpenInterval(dummy, dummy) for any
value of dummy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With