Подтвердить что ты не робот

Почему FRP рассматривает время как фактор ценностей?

Поведение вездесуще определяется как "изменяющееся во времени значение" s 1.

Почему? время, когда зависимость/параметр для разных значений очень необычна.

Моя интуиция для FRP заключалась бы в том, чтобы иметь поведение как переменные значения; он гораздо более распространен, гораздо более простой, я использую гораздо более эффективную идею и достаточно расширяю, чтобы поддерживать время тоже (событие tick).

Например, если вы пишете счетчик, вам не нужны временные метки, связанные с временем/связанными с ними, вам просто нужны события с нажатием кнопки "Увеличить" и "Уменьшить нажатие кнопки".
Если вы пишете игру и хотите поведение позиции/силы, вы просто заботитесь о событиях, связанных с WASD/стрелками, и т.д. (Если вы не запретите своим игрокам перемещаться влево днем, как несправедливо!).

Итак: Почему время - это вообще вопрос? почему временные метки? почему некоторые библиотеки (например, reactive-banana, reactive) принимают значение до значения Future, Moment? Зачем работать с потоками событий, а не просто реагировать на возникновение события? Все это, по-видимому, слишком усложняет простую идею (значение, зависящее от события/события); какой выигрыш? какую проблему мы решаем здесь? (Я хотел бы также получить конкретный пример вместе с замечательным объяснением, если это возможно).

1 Поведение определено так здесь, здесь, здесь... и почти везде, где я встречался.

4b9b3361

Ответ 1

Behavior отличаются от Event прежде всего тем, что a Behavior имеет значение прямо сейчас, а Event имеет значение только всякий раз, когда приходит новое событие.

Итак, что мы подразумеваем под "прямо сейчас"? Технически все изменения реализуются как семантика push или pull по потокам событий, поэтому мы можем только иметь в виду "самое последнее значение из последнего события последствия для этого Behavior". Но это довольно волосатое понятие - на практике "сейчас" намного проще.

Причина, почему "сейчас" проще, сводится к API. Вот два примера из Reactive Banana.

  • В конечном итоге система FRP должна всегда производить какое-то внешне видимое изменение. В Reactive Banana это облегчается функцией reactimate :: Event (IO ()) -> Moment (), которая потребляет потоки событий. Невозможно иметь внешние изменения Behavior триггера --- вы всегда должны сделать что-то вроде reactimate (someBehavior <@ sampleTickEvent), чтобы пробовать поведение в конкретные моменты времени.

  • Поведение Applicative в отличие от Event s. Зачем? Ну, допустим, что Event был аппликативным и думал о том, что происходит, когда мы имеем два потока событий f и x и пишем f <*> x: поскольку события происходят все в разное время, шансы f и x, которые определены одновременно (почти наверняка) 0. Итак, f <*> x всегда означает пустой поток событий, который бесполезен.

    То, что вам действительно нужно, - это f <*> x кэшировать самые последние значения для каждого и принимать их комбинированное значение "все время". Это действительно запутанная концепция, о которой можно говорить в терминах потока событий, поэтому вместо f и x следует учитывать значения для всех точек времени. Теперь f <*> x также определяется как принимающий значения для всех точек во времени. Мы только что придумали Behavior s.

Ответ 2

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

Почему? время, когда зависимость/параметр для разных значений очень необычна.

Я подозреваю, что вы путаете конструкцию (рецепт) поведения с его значением. Например, поведение может быть построено за счет зависимости от чего-то вроде ввода пользователя, возможно, с помощью дополнительного синтетического преобразования. Так вот рецепт. Смысл, однако, является просто функцией времени, связанной с функцией времени, которая является пользователем. Обратите внимание, что под "функцией" я подразумеваю в математическом смысле слова: (детерминированное) отображение из области (времени) в диапазон (значение), а не в том смысле, что существует чисто программное описание.

Я видел много вопросов, которые задают вопрос о том, почему важно время и почему непрерывное время. Если вы применяете простую дисциплину математического значения в стиле денотационной семантики (простой и знакомый стиль для функциональных программистов), вопросы становятся намного яснее.

Если вы действительно хотите понять суть и думать за FRP, я рекомендую вам прочитать мой ответ на "Спецификация для функционального реактивного языка программирования" и следовать указателям, включая "Что такое функциональное реактивное программирование" .

Ответ 3

В документе Conal Elliott Push-Pull FRP описываются события, изменяющиеся по времени, где интересны только моменты времени, когда происходят события. Reactive события, изменяющиеся по времени, представляют собой текущее значение и следующий Event, которые изменят его. Event - это точка Future в изменяющихся событиях Reactive.

data Reactive a = a ‘Stepper ‘ Event a
newtype Event a = Ev (Future (Reactive a))

Future не обязательно иметь время, связанное с ним, просто нужно представить идею значения, которое еще не произошло. Например, на нечистом языке с событиями будущее может быть дескриптором события и значением. Когда событие происходит, вы устанавливаете значение и поднимаете дескриптор.

Reactive a имеет значение для a во все моменты времени, так зачем нам Behavior s? Позвольте сделать простую игру. Между тем, когда пользователь нажимает клавиши WASD, символ, ускоренный применяемым усилием, по-прежнему перемещается по экрану. Позиция символа в разные моменты времени различна, даже если за прошедшее время не произошло никакого события. Это то, что описывает Behavior - то, что не только имеет значение во все моменты времени, но его значение может быть различным во все моменты времени, даже без промежуточных событий.

Одним из способов описания Behavior было бы повторение того, что мы только что заявили. Behavior - это вещи, которые могут изменять промежуточные события. В промежутках между событиями они являются изменяющимися во времени значениями или функциями времени.

type Behavior a = Reactive (Time -> a)

Нам не нужно Behavior, мы могли бы просто добавлять события для тиков часов и писать всю логику во всей игре с точки зрения этих событий тика. Некоторым разработчикам это нежелательно, так как код, объявляющий, что происходит в нашей игре, теперь смешивается с кодом, обеспечивающим его реализацию. Behavior позволяют разработчику разделить эту логику между описанием игры в терминах изменяющихся во времени переменных и реализацией движка, выполняющего это описание.