Как составить несколько монад? IO / Будущее и, возможно, даже с состоянием и опцией

Я пытаюсь составить монады в Scala, выполняя некоторые запросы к серверу. вот фрагмент кода, который я использую. Я стараюсь не использовать плоскую карту, насколько это возможно, только для понимания. Любые идеи? Я знаю, как использовать Monad Transformers, но я не знаю, как составить несколько монад. Может кто-нибудь мне помочь?

for {
  session <- getSession(ticker) //IO[Future[Response]]
  crumbF = session.flatMap(response => Future(parseCrumb(response.body)))
  cookiesF = session.flatMap(response => Future(response.cookies))
  crumb = Await.result(crumbF, 5 seconds) // Future[String]
  cookies = Await.result(cookiesF, 5 seconds) //Future[Seq[Cookies]]
  data <- getData(ticker, startDate, endDate, interval, crumb, cookies.head) // IO[Future[Response]]
  stocksF = data.flatMap { response =>
    import DefaultBodyReadables._
    Future {
      StockDf.mapDataToDf(response.body)
    }
  }
} yield stocksF

person ksp0422    schedule 23.10.2018    source источник
comment
Монады вообще не составляют. Трансформеры — это особые случаи, которые, в некотором смысле, сочиняют. Вы можете сложить несколько трансформеров, чтобы составить несколько монад.   -  person n. 1.8e9-where's-my-share m.    schedule 23.10.2018
comment
Вы пытаетесь составить монады, то есть поместить одну монаду в другую, как Future с Option внутри, или вы пытаетесь работать с разными монадами в одном for понимании?   -  person Grisha    schedule 23.10.2018
comment
Неясно, правильно ли использовать этот код for. Все эти присваивания и операторы Await были бы понятнее, если бы они были написаны как обычный код. В конце концов, это всего лишь map, вложенное в flatMap, и, вероятно, написанное таким образом выглядело бы яснее. И зачем вызывать flatMap и заключать результат в Future, а не просто вызывать map?   -  person Tim    schedule 23.10.2018


Ответы (1)


Итак, несколько вещей.

Если вы запускаете фьючерсы внутри для понимания, то они будут работать последовательно, а не параллельно — если это ваше намерение, то все в порядке. Если нет, то создайте их за пределами для понимания.

Вы не можете смешивать монадические контексты внутри для понимания.

// Yes
for {
  a <- Some(5)
  b <- Some(10)
} yield 5 * 10

// No
for {
  a <- Some(5)
  b <- Future(10)
} yield 5 * 10
person Terry Dactyl    schedule 23.10.2018