Agreed about none of the alternatives seeming like improvements. Haskell's syntax for this is elegant, but it works because (1) the type signature is written separately and (2) the switched-on parameters are all explicit and so can be easily pattern-ized. In other words, it works because there's already some verbosity that people take for granted.
I wonder how much of the clunkiness here is just the extra level of bracing required. Like if you had:
func canAdvance() -> Int = switch { // implicitly over self
case .green: return true
default: return false
}