Как это для понимания построить состояние, одновременно подчеркивая? - PullRequest
0 голосов
/ 08 июня 2018

Фон
Значение forExpression (ниже) возвращает монаду StateT, которая принимает в качестве параметра начальное состояние, добавляет 2 и 3 к состоянию, а затем умножает это на 10.

Вопрос
Почему функции add(2) и add(3) выполняются, когда этот экземпляр StateT выполняется после того, как эти две функции, кажется, отбрасывают свой результатприсваивая его подчеркиванию?

Пример
, если вы оцениваете forExpression с начальным состоянием IntState(1), почему он возвращает IntState(60) вместо IntState(10)?

Ниже приведен минимальный фрагмент кода, или вы можете просмотреть полный исходный код на github .

Этот код был обнаружен при чтении "Упрощенного функционального программирования" Элвина Александра.

  case class IntState(i: Int)

  def add(i: Int) = StateT[IO, IntState, Int] { oldState =>
    val newValue = i + oldState.i
    val newState = oldState.copy(i = newValue)
    IO((newState, newValue))
  }

  def multiply(i: Int) = StateT[IO, IntState, Int] { oldState =>
    val newValue = i * oldState.i
    val newState = oldState.copy(i = newValue)
    IO((newState, newValue))
  }

  val forExpression: StateT[IO, IntState, Int] = for {
    _ <- add(2)
    _ <- add(3)
    x <- multiply(10)
  } yield x

1 Ответ

0 голосов
/ 08 июня 2018

Простое высокоуровневое объяснение: StateT вычисления имеют отдельное состояние и результат (например, newState и newValue в IO((newState, newValue)) в вашем коде).Слева от <- отображается часть newValue, и только она игнорируется в _ <- ....Манипулирование newState неявно, и оно не выбрасывается.

Для низкого уровня вы можете:

  1. Перевести для понимания в flatMap.

  2. Разверните определение StateT flatMap.

  3. Посмотрите, что происходит с состоянием в функции результата.

...