Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The signature of mapNotNull is wrong. #192

Closed
HideakiSago opened this issue Dec 25, 2022 · 1 comment · Fixed by #197
Closed

The signature of mapNotNull is wrong. #192

HideakiSago opened this issue Dec 25, 2022 · 1 comment · Fixed by #197

Comments

@HideakiSago
Copy link

HideakiSago commented Dec 25, 2022

Problem

extension RequireNoNullsKtIterableExtension<T> on KtIterable<T?> {

/// Returns a list containing the results of applying the given [transform] function
/// to each element in the original collection.
KtList<R> mapNotNull<R>(R? Function(T?) transform) {
final mapped = mapNotNullTo(mutableListOf<R>(), transform);
// TODO ping dort-lang/sdk team to check type bug
// When in single line: type "DartMutableList<String>' is not a subtype of type 'Null"
return mapped;
}
/// Applies the given [transform] function to each element in the original collection
/// and appends only the non-null results to the given [destination].
C mapNotNullTo<R, C extends KtMutableCollection<R>>(
C destination, R? Function(T?) transform) {
for (final item in iter) {
final result = transform(item);
if (result != null) {
destination.add(result);
}
}
return destination;
}
}

This causes a build error with the following code:

      listOf("not null").mapNotNull((it) => it.startsWith("not") ? it : null); // error!!
      listOf("not null", null).mapNotNull((it) => it?.startsWith("not") == true ? it : null);

The following code in Kotlin did not cause a build error .

        listOf("not null").mapNotNull { if (it.startsWith("not")) it else null }
        listOf("not null", null).mapNotNull { if (it?.startsWith("not") == true) it else null }

It looks like the signature of RequireNoNullsKtIterableExtension.mapNotNull is wrong.

Suggestion

Quoting the implementation of mapNotNull from kotlin.collections:

/**
 * Returns a list containing only the non-null results of applying the given [transform] function
 * to each element in the original collection.
 * 
 * @sample samples.collections.Collections.Transformations.mapNotNull
 */
public inline fun <T, R : Any> Iterable<T>.mapNotNull(transform: (T) -> R?): List<R> {
    return mapNotNullTo(ArrayList<R>(), transform)
}

/**
 * Applies the given [transform] function to each element in the original collection
 * and appends only the non-null results to the given [destination].
 */
public inline fun <T, R : Any, C : MutableCollection<in R>> Iterable<T>.mapNotNullTo(destination: C, transform: (T) -> R?): C {
    forEach { element -> transform(element)?.let { destination.add(it) } }
    return destination
}

The following code seems fine.

extension _<T> on KtIterable<T> {
  /// Returns a list containing the results of applying the given [transform] function
  /// to each element in the original collection.
  KtList<R> mapNotNull2<R>(R? Function(T) transform) {
    final mapped = mapNotNullTo(mutableListOf<R>(), transform);
    // TODO ping dort-lang/sdk team to check type bug
    // When in single line: type "DartMutableList<String>' is not a subtype of type 'Null"
    return mapped;
  }

  /// Applies the given [transform] function to each element in the original collection
  /// and appends only the non-null results to the given [destination].
  C mapNotNullTo<R, C extends KtMutableCollection<R>>(C destination, R? Function(T) transform) {
    for (final item in iter) {
      final result = transform(item);
      if (result != null) {
        destination.add(result);
      }
    }
    return destination;
  }
}

Note that the code above is an extension of KtIterable<T>.

I thought mapNotNull should be defined in
extension KtIterableExtensions<T> on KtIterable<T> or
extension ChainableKtIterableExtensions<T> on KtIterable<T>.

Version

This problem happened when I upgraded from 0.9.1 to 1.0.0.

   kt_dart: ^0.9.1 -> ^1.0.0
@passsy
Copy link
Owner

passsy commented Mar 20, 2023

Thanks for bringing this up. The signature of mapNotNull and others works now fine for non-nullable types.

Please update to kt_dart: ^1.1.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants