расскажите как изменится решение, чтобы отсортировать пользователей не как на скриншоте, а в натуральном порядке (user8, user9, user10, user11)
Как мы обсуждали ранее
Списки могут работать с Function2, которые являются моноидом
Iterable.sort(function2: Function2Monoid<A, Order>)
Function2 имеет тип (A, A) -> Order. Как раз она решает что и как сортировать
То есть если нам нужен любой другой вид сравнения,
мы реализуем Function2 по-другому
val <A> ((A) -> String).customComparator
get():Function2Monoid<A, Order> = Function2Monoid<A, Order> { a, other ->
val aString = invoke(a)
val otherString = invoke(other)
//сравниваем значения строк как нам нужно
//возвращаем Order, который нам нужен при сравнении
return@Function2Monoid Order.EQ
}
Чтобы доказать, что (A, A) -> Order.
Мы должны были доказать, что Order это моноид
ComparatorMonoid::plus — не делает ли данная функция лишние сравнения?
Правильное замечание, делает.
Но тут есть два пути развития
1)Следующим шагом, после того, как мы доказали что (A, A) -> Order моноид
Оптимизировать его, чтобы он не делал лишних сравнений
fun interface ComparatorMonoid<A> : Monoid<ComparatorMonoid<A>> {
fun compare(a: A, other: A): Order
override fun plus(rh: ComparatorMonoid<A>) =
ComparatorMonoid<A> { a, other ->
val order = compare(a, other)
when (order) {
Order.EQ -> rh.compare(a, other)
else -> order
}
}
override fun empty() = ComparatorMonoid<A> { _, _ -> Order.EQ }
}
2)Либо пойти по правильному функциональному пути
Так, как обсуждалось ранее
Если область значения функции моноид, то такая функция также моноид
Реализуем это в коде
fun interface Function2Monoid<A, B : Monoid<B>> : Monoid<Function2Monoid<A, B>> {
fun invoke(a: A, other: A): B
override fun plus(rh: Function2Monoid<A, B>): Function2Monoid<A, B> =
Function2Monoid { a, other -> invoke(a, other) + rh.invoke(a, other) }
override fun empty() = Function2Monoid<A, B> { a, a1 ->
invoke(a, a1).empty()
}
}
И теперь нам не нужно создавать ComparatorMonoid
Мы можем пользоваться Function2Monoid
Тут и пригодится знание о том, что Order это моноид, которое легко доказать
Переписав функции в такой вид
fun <A> Iterable<A>.sort(comparatorMonoid: Function2Monoid<A, Order>) =
sortedWith { a, b -> comparatorMonoid.invoke(a, b).compareValue }
fun <A : Comparable<A>> A.compare(other: A) = when {
this > other -> Order.GT
this == other -> Order.EQ
else -> Order.LT
}
val <A, B : Comparable<B>> ((A) -> B).comparator
get():Function2Monoid<A, Order> = Function2Monoid<A, Order> { a, b ->
invoke(a).compare(invoke(b))
}
Не хотел этим усложнять статью.
Но, видимо, стоило.
Соглашусь с вами, наверное, некорректно сравнивать продукт на ранней стадии разработки с готовым продуктом. Но моя цель была сравнить, на каком этапе разработки сейчас представленные на конференциях продукты.
Как мне показалась, это интересная тема.
Насчет того, что сначала стоило посмотреть первоисточник — я с первоисточника и начал. И я понимал, что Compose в очень ранней стадии разработки и понимал, что гугл сказал, что хочет собрать обратную связь от разработчиков. Но при этом всем, когда начал смотреть Compose, в голове держал, то что Google уже создал Flutter, который вызвал большой интерес у Android разработчиков. И что у Google уже есть обратная связь по Flutter от тех же разработчиков, от которых просит обратную связь по Compose. И ждал от Compose, то что он будет реализован на основе отзывов о Flutter, хоть и на уровне концепции. А по факту, сейчас Compose — это пара полурабочих вьюх. Какого отзыва Google ждет и может ждать на основе такого? Складывается ощущение, что Google было важно анонсировать хоть что-то.
Насчет статьи надеюсь, хоть кому-то она была полезна.
такой код в моем презентере. Именно в такой реализации таймер стопится. После вопроса я специально запустил приложение и проверил.
Приведенную вами библиотеку я не рассматривал. Но видно, что либа строит мост в native и там уже реализуется таймер. Понятное дело, мне ничто не мешает сделать foreground service в Android, запустить в нем таймер и общатьсяс c js через мост, даже без использование либы. И такой таймер на родных прошивках в Android убиваться не будет в принципе.
То что я писал это про выполнение JS
Так как приложения очень маленькие — скорость их работы визуально одинакова. Сначала я думал сравнить сколько будут весить Apk для Android. Но сравнивать размеры тоже было некорректно, т.к.:
1)В React Native был добавлен Realm, нативная часть которого очень утяжелила Apk.
2)В Android я запихнул кучу библиотек, без которых я считаю, как “истинный Android разработчик“, приложению не обойтись.
1)Почему не попал ionic? Потому что, лично для меня, были интересны React Native и Flutter
2)Главное для меня при разработке приложений — это их поддерживаемость. Да, я понимаю, что кроссплатформа быстрее и кажется на первый взгляд выгоднее для бизнеса. Но в долгосрочной перспективе, по моему мнению, она себя не окупит, так как все равно придется писать мост к нативу, когда нужно будет писать что-то специфическое под платформу. Хотя, если я буду писать домашний проект, я склонюсь к Flutter.
Тут нужно обратить внимание: при уходе в фон убивается процесс приложения или нет. В ios процесс убивается у свернутого приложения, через некоторое время. И убийство процесса никакой из вариантов не переживет. А если рассматривать ситуацию сворачивания в Android до момента убийства процесса, то Flutter нормально работает и время не останавливается. А в React Native таймер зависает
Жор батарейки мною не рассматривался. Насчет скорости — разрабатываемые приложения очень маленькие. Всего 3 экрана. И разницу в скорости визуально ощутить не получилось, так как все приложения выглядят шустро. А программное измерение скорости я не производил
Выдержка из статьи про RxSwift
оператор — observeOn
Указывает, на каком Scheduler должен выполнять свою работу Observer, особенно критично при работе с GUI.
1) Искать библиотеки можно тут
2) Не могу компетентно ответить на этот вопрос. Но есть русскоязычный чат о Dart в telegram, думаю там вам с удовольствием ответят.
Как мы обсуждали ранее
Списки могут работать с Function2, которые являются моноидом
Iterable.sort(function2: Function2Monoid<A, Order>)
Function2 имеет тип (A, A) -> Order. Как раз она решает что и как сортировать
То есть если нам нужен любой другой вид сравнения,
мы реализуем Function2 по-другому
И после этого можем его использовать в сортировке
Учим наши функции работать с nullable)
Плюс для улучшения Api можно посмотреть в сторону оптики
Это сделано для очевидности доказательства
Чтобы доказать, что (A, A) -> Order.
Мы должны были доказать, что Order это моноид
Правильное замечание, делает.
Но тут есть два пути развития
1)Следующим шагом, после того, как мы доказали что (A, A) -> Order моноид
Оптимизировать его, чтобы он не делал лишних сравнений
2)Либо пойти по правильному функциональному пути
Так, как обсуждалось ранее
Если область значения функции моноид, то такая функция также моноид
Реализуем это в коде
И теперь нам не нужно создавать ComparatorMonoid
Мы можем пользоваться Function2Monoid
Тут и пригодится знание о том, что Order это моноид, которое легко доказать
Переписав функции в такой вид
Не хотел этим усложнять статью.
Но, видимо, стоило.
Как мне показалась, это интересная тема.
Насчет того, что сначала стоило посмотреть первоисточник — я с первоисточника и начал. И я понимал, что Compose в очень ранней стадии разработки и понимал, что гугл сказал, что хочет собрать обратную связь от разработчиков. Но при этом всем, когда начал смотреть Compose, в голове держал, то что Google уже создал Flutter, который вызвал большой интерес у Android разработчиков. И что у Google уже есть обратная связь по Flutter от тех же разработчиков, от которых просит обратную связь по Compose. И ждал от Compose, то что он будет реализован на основе отзывов о Flutter, хоть и на уровне концепции. А по факту, сейчас Compose — это пара полурабочих вьюх. Какого отзыва Google ждет и может ждать на основе такого? Складывается ощущение, что Google было важно анонсировать хоть что-то.
Насчет статьи надеюсь, хоть кому-то она была полезна.
Вот какая реализация во флатере
Я объективно ответил на комментарий — проверив, запустив разработанные приложения
такой код в моем презентере. Именно в такой реализации таймер стопится. После вопроса я специально запустил приложение и проверил.
Приведенную вами библиотеку я не рассматривал. Но видно, что либа строит мост в native и там уже реализуется таймер. Понятное дело, мне ничто не мешает сделать foreground service в Android, запустить в нем таймер и общатьсяс c js через мост, даже без использование либы. И такой таймер на родных прошивках в Android убиваться не будет в принципе.
То что я писал это про выполнение JS
1)В React Native был добавлен Realm, нативная часть которого очень утяжелила Apk.
2)В Android я запихнул кучу библиотек, без которых я считаю, как “истинный Android разработчик“, приложению не обойтись.
2)Главное для меня при разработке приложений — это их поддерживаемость. Да, я понимаю, что кроссплатформа быстрее и кажется на первый взгляд выгоднее для бизнеса. Но в долгосрочной перспективе, по моему мнению, она себя не окупит, так как все равно придется писать мост к нативу, когда нужно будет писать что-то специфическое под платформу. Хотя, если я буду писать домашний проект, я склонюсь к Flutter.
оператор — observeOn
Указывает, на каком Scheduler должен выполнять свою работу Observer, особенно критично при работе с GUI.
Консоль:
Main: false Event: next(A)
Main: false Event: next(B)
Main: true Event: next(1)
Main: true Event: next(2)
Main: true Event: next(3)
Main: true Event: completed
Main: false Event: next(C)
Main: false Event: completed
2) Не могу компетентно ответить на этот вопрос. Но есть русскоязычный чат о Dart в telegram, думаю там вам с удовольствием ответят.