Функциональное программирование в упражнении Scala 6.11. Как это работает для понимания? - PullRequest
4 голосов
/ 28 октября 2019

Код здесь: https://github.com/fpinscala/fpinscala/blob/master/answers/src/main/scala/fpinscala/state/State.scala

  def simulateMachine(inputs: List[Input]): State[Machine, (Int, Int)] = for {
    _ <- sequence(inputs map ((modify[Machine] _) compose update))
    s <- get
  } yield (s.coins, s.candies)

Я не понимаю, как вторая строка s <- get работает в этом для понимания.

Насколько я вижу, в первой строке создается State [Machine, List [Unit]], а flatMap выбрасывает List [Unit] с _.

Впоследствии во второйСтрока, я не понимаю, как get применяется к Machine, созданному в первой строке. Как проходит Machine?

РЕДАКТИРОВАТЬ: Спасибо jwvh и Маркусу Аппелю за ответы, теперь я понимаю, что get - это метод без параметров, который возвращает State[S, S].

Теперь я думаю, что понял, но, пожалуйста, поправьте меня, если я ошибаюсь. Во-первых, я расширил понимание, как показано ниже.

sequence(inputs map ((modify[Machine] _) compose update))
    .flatMap(_ => get
        .map(s => (s.coins, s.candies))

get.map(s => (s.coins, s.candies) можно заменить на State(s => (s, s)).map(s => (s.coins, s.candies) и в конечном итоге State(s => (s, (s.coins, s.candies)))

sequence(inputs map ((modify[Machine] _) compose update))
    .flatMap(_ => State(s => (s, (s.coins, s.candies))))

Подставляя внешний sequence(inputs map ((modify[Machine] _) compose update)).flatMap с определением, я вижу

State(s => {
    val (a, s1) = sequence(inputs map ((modify[Machine] _) compose update)).run(s)
    f(a).run(s1)
  })

Теперь я заменяю f(a) оценкой _ => State(s => (s, (s.coins, s.candies)))

State(s => {
    val (a, s1) = sequence(inputs map ((modify[Machine] _) compose update)).run(s)
    State(s => (s, (s.coins, s.candies))).run(s1)
  })

По существу, sequence(inputs map ((modify[Machine] _) compose update)) производит Machine в конечном состоянии после выполнения списка входов и производитвыход типа State[Machine, List[Unit]]. Но фактическое Machine в этом государстве явно не передается. Скорее, он передается неявно по определению flatMap, когда он вызывает State(s => (s, (s.coins, s.candies))).run(s1) через .run(s1).

1 Ответ

0 голосов
/ 28 октября 2019

Как уже указывал @jwvh, get - это метод, определенный в object State. get -метод не применяется ни к какому-либо Machine, а Machine не используется в качестве параметра, поскольку функция имеет следующую подпись:

def get[S]: State[S, S] = State(s => (s, s))

Это означает, что get не имеет параметров итип возвращаемого значения State[S, S].

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