powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / Java [игнор отключен] [закрыт для гостей] / scala задачка на мап флатмап
25 сообщений из 31, страница 1 из 2
scala задачка на мап флатмап
    #39824625
andreykaT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
собссно есть структура Future[Set[Future[Int]] надо из нее сделать Future[Set[Int]]

у меня уже мозг плавится как их там разложить.
...
Рейтинг: 0 / 0
scala задачка на мап флатмап
    #39824631
andreykaT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вопрос снят:

автор in.foldLeft(successful(cbf(in))) {
(fr, fa) => fr.zipWith(fa)(_ += _)
}.map(_.result())(InternalCallbackExecutor)
...
Рейтинг: 0 / 0
scala задачка на мап флатмап
    #39824662
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreykaTсобссно есть структура Future[Set[Future[Int]]
Ну это какой-то треш, кратко говоря проблема в том что кто-то довел до такой обертки. Set[Future[Int]] элементарно переводится в Future[Set[Int]] через метод sequence. Соответственно там у тебя есть метод который оборачивает все в ещё один Future - лучше проапдейтить метод, чтобы доп обёртка просто не создавалась, ну а если нельзя - то просто вызываем flatten и дело в шляпе.

Код решения, даже мне с ФП головного мозга кажется клочком, после которого хочется окунуться назад в java. Теперь я понимаю почему тебе скала так тяжело заходит, с таким то Легаси кодом
...
Рейтинг: 0 / 0
scala задачка на мап флатмап
    #39824667
andreykaT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
поздравляю тебя. это исходник того метода, который ты мне только что посоветовал.

я тоже с тобой согласен что исходники скальных утильных либ - это лютый пиндец. в основном. но это не точно.
...
Рейтинг: 0 / 0
scala задачка на мап флатмап
    #39824669
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А какой прикладной смысл в вложенных фьючерсах? Хотелось-бы пример из реальной жизни.
...
Рейтинг: 0 / 0
scala задачка на мап флатмап
    #39824671
andreykaT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл никandreykaTсобссно есть структура Future[Set[Future[Int]]
Ну это какой-то треш, кратко говоря проблема в том что кто-то довел до такой обертки. Set[Future[Int]] элементарно переводится в Future[Set[Int]] через метод sequence. Соответственно там у тебя есть метод который оборачивает все в ещё один Future - лучше проапдейтить метод, чтобы доп обёртка просто не создавалась, ну а если нельзя - то просто вызываем flatten и дело в шляпе.

Код решения, даже мне с ФП головного мозга кажется клочком, после которого хочется окунуться назад в java. Теперь я понимаю почему тебе скала так тяжело заходит, с таким то Легаси кодом
как такая матрёшка вышла ответ очень простой -
мы ходим в базу за данными, прилетает футура.

с данными из базы мы идем на сервис через веб, с которого снова прилетает футура
с полученными данными с сервиса мне надо еще раз сходить в базу и проапдейтить данные - и здесь прилетает футура.

согласись, что набор действий более чем банальный. я бы мог флатмапом всё разложить. но в третьем шаге надо обходить полученный список последовательно и там и вылетает сет футур.
...
Рейтинг: 0 / 0
scala задачка на мап флатмап
    #39824672
andreykaT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonА какой прикладной смысл в вложенных фьючерсах? Хотелось-бы пример из реальной жизни.
это просто дань моде. а так есть мнение что экзекутор "типа" более правильно всё разложит-распараллелит там где можно и выйдет "типа" оптимальнее. сам лично не проверял. в книжках такое мнение читал. верю написанному.
...
Рейтинг: 0 / 0
scala задачка на мап флатмап
    #39824683
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Структурно - похоже на RecursiveAction/ForkJoin
...
Рейтинг: 0 / 0
scala задачка на мап флатмап
    #39824700
andreykaT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да форкджойн. Но там ты руками все делаешь. А тут типа оно само тебя заставляет)) матрехи писать да раскладывать на монады-функторы.
Кстати, форкджойн имхо не взлетел.
...
Рейтинг: 0 / 0
scala задачка на мап флатмап
    #39825132
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще Future не самый лучший инструмент в Scala и ФП. Предпочтительнее юзать monix.Task либо IO из Cats\ScalaZ. Основной косяк Future - что он начинает исполнение сразу после создания и девелопер никак не контролирует это, что приводит к потере referrential transparency. Но это лирика.

Если я правильно понял задачу, то не вижу в ней ничего сложного, если хочешь можешь добавить недостаюшие детали а я потом попробую привести решение. Итак

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
import scala.concurrent.{Await, Future}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.Duration

object Test extends App{

  type OrderId = Int
  type ItemId = Int
  case class Order(OrderId:Int, items:Set[ItemId])
  case class Item(id:ItemId)

  def lookupOrder(id:OrderId):Future[OrderId] = {
    println(s"Retrieving order $id")
    Thread.sleep(500)
    println(s"Order retrieved")
    Future(id)
  }
  def fetchOrder(id:OrderId):Future[Order] = {
    println(s"Fetching order $id")
    Thread.sleep(500)
    println(s"Order fetched")
    Future(Order(id, Set(1,2,3,4,5)))
  }

  def fetchItem(id:ItemId) : Future[Item] = {
    println(s"Fetching item $id")
    Thread.sleep(5000)
    println(s"item fetched")
    Future(Item(id))
  }

  def program(id:OrderId) = {
    val future: Future[Set[Item]] = for {
      orderId <- lookupOrder(id)
      order <- fetchOrder(orderId)
      items <- Future.sequence(order.items.par.map(fetchItem).seq)
    } yield items
    val result = Await.result(future, Duration.Inf)
    println(s"Fetched items ${result.mkString(",")}. Done!")
  }

  program(1)
}


В общем-то все тривиально
...
Рейтинг: 0 / 0
scala задачка на мап флатмап
    #39825134
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
lookupOrder - берем данные из базы
fetchOrder - идем на рест и ретривим айтемы
fetchItem - берем из базы детали по каждому айтему

Все правильно ведь?
...
Рейтинг: 0 / 0
scala задачка на мап флатмап
    #39825137
andreykaT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
так да. я в итоге так и сделал. через фьюча-сиквенз.
и в общем то код по строкам вышел в несколько строк как по-сути и у тебя.

без фьюча-сиквенз разложить эти монады-функторы у тебя так же лаконично без вырвиглазного набора символов увы не выйдет.

ну или мне мозгов не хватило как.

насчет скалаз и пр ну это совсем уже функционализм головного мозга. скала всё же не чистый ФП это мультипарадигма ООП и рюшки ФП я считаю, вполне (на мой взгляд) сбалансировано.
...
Рейтинг: 0 / 0
scala задачка на мап флатмап
    #39825139
andreykaT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...ну разве что я сделал на флатмап-мапах а не на форкомпрехеншене как ты. впрочем, это одно и то же.
...
Рейтинг: 0 / 0
scala задачка на мап флатмап
    #39825144
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonСтруктурно - похоже на RecursiveAction/ForkJoin

На самом деле вообще ничего похожего. Тут Струтктура такая - колл 1-> колл 2 зависящий от колл 1 -> N коллов зависящих от колл2(но не зависящих друг от друга).

Банальный тредпул. В форкджойне вся соль в том что там рекурсивные таски, которые сплитятся на более мелкие, и одни из них зависят от других
...
Рейтинг: 0 / 0
scala задачка на мап флатмап
    #39825146
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreykaT
без фьюча-сиквенз разложить эти монады-функторы у тебя так же лаконично без вырвиглазного набора символов увы не выйдет.


Ну так для этого sequence и придумали. На самом деле все глубже, это один из ФП паттернов, но в отличие от ООП паттернов, он заимплментирован в коде, причем раз и навсегда, в отличие от... списка печатных инструкций ООП:)

sequence он гораздомасштабнее, его надо применять когда у тебя структура данных имеет тип F[G[A]] а тебе надо поменять на G[F[A]], например это может быть List[Option[Int]] -> Option[List[Int]] или List[Future[Int]] -> Future[List[Int]].

List в данном случае представляет собой абстракцию Traversable(но это может быть и другие типы данных, в том числе твой Order), у которой есть метод sequence, и ему до лампочки какой вложенный тип - Future,Either,Option и т.д. Он просто выворачивает структуру наизнанку, вот она красота ФП во всей ее мощи. То что код смотрится ужасным с точки зрения имплементации sequence - ну что ж, это цена за супер-абстракцию, недостижимую для ООП. Собственно вся сложность в изучении ФП сводится к изучению такого рода паттернов, и да это требьует времени, но рано или поздно даже такой синтаксис становится читаемым
...
Рейтинг: 0 / 0
scala задачка на мап флатмап
    #39825149
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл никБанальный тредпул. В форкджойне вся соль в том что там рекурсивные таски, которые сплитятся на более мелкие, и одни из них зависят от других
Нет. В случае использования RecursiveAction ничего ни от кого не зависит.
А соль в том что диспетчеризация очень простая. Пул загружен на 100% эффективно.
...
Рейтинг: 0 / 0
scala задачка на мап флатмап
    #39825150
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreykaTДа форкджойн. Но там ты руками все делаешь. А тут типа оно само тебя заставляет)) матрехи писать да раскладывать на монады-функторы.
Кстати, форкджойн имхо не взлетел.
Беда в том что у нас с вами нет объективного теста который бы показал что там перформит лучше.
Пока я просто вижу игры разума. Ну написал так. Потом эдак. Потом еще 100500 способов как решить
задачу. Вплоть до brainfuck.

А что зайдет в продуктив? Вот мой вопрос.
...
Рейтинг: 0 / 0
scala задачка на мап флатмап
    #39825153
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonНет. В случае использования RecursiveAction ничего ни от кого не зависит.
Ну как это не зависит? Если RecursiveAction создает подтаски, то она заканчивается только когда сабтаски закончили исполнение. В случае тредпула этот экшен висел бы и занимал отдельную нить, в случае форкджойна такого не будет, собственно он для этого и был создан.
maytonА соль в том что диспетчеризация очень простая. Пул загружен на 100% эффективно.
Не понял при чем здесь диспетчеризация. А насчет загруженности - очень легко можно написать код который будет создавать тысячу RecursiveAction но каждый этот таск будет зависеть от всех остальных, так что по итогу все будет выполняться фактичски последовательно. Например у нас есть лист из 1000 элементов и мы создаем экшен в котором суммируем элемент и некую функцию от всех остальных элементов.
Если ты про work steal - то да, это делает пул более эффективным, но это никаким образом не относится к задаче ТС
...
Рейтинг: 0 / 0
scala задачка на мап флатмап
    #39825154
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonБеда в том что у нас с вами нет объективного теста который бы показал что там перформит лучше.
Пока я просто вижу игры разума. Ну написал так. Потом эдак. Потом еще 100500 способов как решить
задачу. Вплоть до brainfuck.

А что зайдет в продуктив? Вот мой вопрос.
Не всегда определящим фактором является перфоманс. Иногда безопасность, тестируемость, расширяемость на порядок важнее. В случае форк-джойна ты намертво привязан к нему, ко всей этой инфраструктуре, у твоего заказчика не было задачи - разбить лист на recursiveAction и сджойнить их рлдучив тем самым сумму. Скорее задача - просто посчитать сумму, и в случае ФП, вот этот вот энвайрнмент можно абстрагировать в типе программы и сделать ортогональным.

Поясню на примере, задачу ТС можно было написать так -
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
import scala.concurrent.{Await, Future}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.Duration

object Test extends App{

  type OrderId = Int
  type ItemId = Int
  case class Order(OrderId:Int, items:Set[ItemId])
  case class Item(id:ItemId)

  def lookupOrder(id:OrderId):M[OrderId] = {
    M.unit(id)
  }
  def fetchOrder(id:OrderId):M[Order] = {
    M.unit(Order(id, Set(1,2,3,4,5)))
  }

  def fetchItem(id:ItemId) : M[Item] = {
    M.unit(Item(id))
  }

  def program(id:OrderId, m:M:Monad) = {
    val definitionOfProgram: M[Set[Item]] = for {
      orderId <- lookupOrder(id)
      order <- fetchOrder(orderId)
      items <- m.sequence(order.items.par.map(fetchItem).seq)
    } yield items
    val result = m.run(definitionOfProgram)
    println(s"Fetched items ${result.mkString(",")}. Done!")
  }

  program(1, Future) -- для продакшена
  program(1, Id) -- для тестов

}
 
trait Monad{
  unit() - поместить в контекст
  flatMap - вычислить следущий компутейшен в цепочке
  run - выйти из контекста
}

Id extends Monad {
   unit == noop
   flatMap == просто вызов следующего по цепочке
   run == вернуть значение
}



Таким образом, можно всего лишь одной(!) строкой поменять исполнение программы из многопоточного в однопоточный(для тестов)
...
Рейтинг: 0 / 0
scala задачка на мап флатмап
    #39825189
andreykaT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Чет я не понял где эта важная одна строка?
...
Рейтинг: 0 / 0
scala задачка на мап флатмап
    #39825193
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
program(1, Future) -- для продакшена
program(1, Id) -- для тестов
...
Рейтинг: 0 / 0
scala задачка на мап флатмап
    #39825194
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есественно это псевдокод, чтобы не загружать scala деталями. Но итог тот же. Финальный вызов будет program[Monad](params)
...
Рейтинг: 0 / 0
scala задачка на мап флатмап
    #39825240
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл никНе всегда определящим фактором является перфоманс. Иногда безопасность, тестируемость, расширяемость на порядок важнее. В случае форк-джойна ты намертво привязан к нему, ко всей этой инфраструктуре, у твоего заказчика не было задачи - разбить лист на recursiveAction и сджойнить их рлдучив тем самым сумму. Скорее задача - просто посчитать сумму, и в случае ФП, вот этот вот энвайрнмент можно абстрагировать в типе программы и сделать ортогональным.

Не согласен. В случае форк-джойна во главу угла ставится перформанс. Остальные фичи не имеют значения.
Но обсуждая форк мы уклонились от задачи автора. У него задача была сделать Future[Set[Int]] из чего-то там.

Другие критерии - неизвестны. Поэтому тут любой способ хорош.
...
Рейтинг: 0 / 0
scala задачка на мап флатмап
    #39825247
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonзабыл никНе всегда определящим фактором является перфоманс. Иногда безопасность, тестируемость, расширяемость на порядок важнее. В случае форк-джойна ты намертво привязан к нему, ко всей этой инфраструктуре, у твоего заказчика не было задачи - разбить лист на recursiveAction и сджойнить их рлдучив тем самым сумму. Скорее задача - просто посчитать сумму, и в случае ФП, вот этот вот энвайрнмент можно абстрагировать в типе программы и сделать ортогональным.

Не согласен. В случае форк-джойна во главу угла ставится перформанс. Остальные фичи не имеют значения.
Но обсуждая форк мы уклонились от задачи автора. У него задача была сделать Future[Set[Int]] из чего-то там.

Другие критерии - неизвестны. Поэтому тут любой способ хорош.
Автор java concurrency in practice and jvm architect - Brian Goetz describes the situation best: https://www.ibm.com/developerworks/library/j-jtp11137/index.html

Using conventional thread pools to implement fork-join is also challenging because fork-join tasks spend much of their lives waiting for other tasks. This behavior is a recipe for thread starvation deadlock, unless the parameters are carefully chosen to bound the number of tasks created or the pool itself is unbounded. Conventional thread pools are designed for tasks that are independent of each other and are also designed with potentially blocking, coarse-grained tasks in mind — fork-join solutions produce neither.



Work stealing немного ускоряет обработку но это лишь бонус. Вообще почитай тред - https://stackoverflow.com/questions/21156599/javas-fork-join-vs-executorservice-when-to-use-which
Там много интересного
...
Рейтинг: 0 / 0
scala задачка на мап флатмап
    #39825253
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо. Почитаем
...
Рейтинг: 0 / 0
25 сообщений из 31, страница 1 из 2
Форумы / Java [игнор отключен] [закрыт для гостей] / scala задачка на мап флатмап
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]