Using instance methods of `Type` in map, filter and friends for collections of `Type` instances

I understand that using properties directly in map and friends is already under development in SE-0249 .

In a similar way, I'd like to us appropriate instance functions on type T on collections of instances of type T. Suppose I have the collection of ASCII characters.

let asciiChars = (0...127).compactMap(Unicode.Scalar.init).map(Character.init)

In this example, you can already see that I'm using init of Character and Unicode.Scalar in map calls to apply the inits to the elements of the collection, as the initialiser have types (Int) -> Unicode.Scalar? and (Unicode.Scalar) -> Character respectively, which fit the requirements of map.

Now, I'd like to be able to do this for instance functions as well. Suppose I have this extension of Character:

extension Character {
  func checkIsValidAsciiDigit() -> Bool {
    return isASCII && isWholeNumber
  }
}

now I'd like to do this:

let filteredDigits = "abc123def456".filter(Character.checkIsValidAsciiDigit)
// filteredDigits should now be "123456"

but I can't, because Character.checkIsValidAsciiDigit is of type (Character) -> () -> Bool but filter expects (Character) -> Bool in this case. I get that.

But it seems like it should work, and afaict, I can easily write a function for myself to make this work for all relevant cases involving filter + map.

func flattenFunc<Input, Output>(_ f: @escaping (Input) -> () -> Output) -> (Input) -> Output {
  return { param in
    return f(param)()
  }
}

now I can simply write

let filteredDigits = "abc123def456".filter(flattenFunc(Character.checkIsValidAsciiDigit))

and everything works as expected.

Now my questions are:

  • Am I correct that this kind of automatic flattening for instance methods from types does not exist yet?
  • Is something in development or was discussed before that would enable this behavior?
  • Is it worth to write a pitch for this or was this maybe discussed before? Are there inherent reasons why such an automatic flattening couldn't be inferred?
2 Likes

For instance method specifically, it was discussed and accepted before in SE-0042 but the implementation didn't land in-time and so it was subsequently rejected.

1 Like

What was the reason to reject it instead of implementing it later? Is it because the change proposed there wasn’t source compatible? Or is there another reason?

Assuming a source-compatible way could be found (eg adding such a flatten function to the standard library) are there other issues with this?

1 Like

Source compatibility mostly, here.

1 Like