Istnieje więcej niż jeden sposób, aby zrobić FRP i jest to aktywny obszar badań. To, co najlepsze, może w dużej mierze zależeć od tego, jak rzeczy wchodzą ze sobą w interakcje, a nowe i lepsze techniki mogą pojawić się w przyszłości.
Ogólnie rzecz biorąc, chodzi o to, aby zachowania, które są funkcjami czasu zamiast zwykłych wartości (jak powiedziałeś). Zachowania można definiować w kategoriach innych zachowań i można je definiować w celu zamiany innych zachowań w przypadku wystąpienia określonych zdarzeń.
W twoim przykładzie, na ogół nie musisz pamiętać pozycji piłki za pomocą argumentów (ale dla niektórych rodzajów FRP możesz zrobić).Zamiast tego możesz po prostu mieć zachowanie:
ballPos : time -> (float * float)
Może to mieć zasięg globalny lub w przypadku większego programu może być lepiej mieć zakres lokalny z wszystkimi jego zastosowaniami w tym zakresie.
W miarę, jak rzeczy stają się bardziej skomplikowane, będziesz miał zdefiniowane zachowania w coraz bardziej złożony sposób, zależą od innych zachowań i zdarzeń - w tym rekursywne zależności, które są obsługiwane w różny sposób w różnych ramach FRP. W F # dla zależności rekurencyjnych oczekiwałbym, że będziesz potrzebował let rec
, w tym wszystkich zaangażowanych zachowań. Mogą one być nadal zorganizowane w struktury choć - na górnym poziomie mogą mieć:
type alienInfo = { pos : float*float; hp : float }
type playerInfo = { pos : float*float; bombs : int }
let rec aliens : time -> alienInfo array = // You might want laziness here.
let behaviours = [| for n in 1..numAliens ->
(alienPos player n, alienHP player n) |]
fun t -> [| for (posBeh, hpBeh) in behaviours ->
{pos=posBeh t; hp=hpBeh t} |] // You might want laziness here.
and player : time -> playerInfo = fun t ->
{ pos=playerPos aliens t; bombs=playerBombs aliens t}
a następnie zachowań dla alienPos, alienHP można zdefiniować, z zależnościami na odtwarzaczu i playerPos, playerBombs można zdefiniować z zależnościami od kosmitów.
W każdym razie, jeśli możesz podać więcej szczegółów na temat rodzaju używanego FRP, łatwiej będzie udzielić bardziej szczegółowych porad. (A jeśli potrzebujesz porady, jakiego rodzaju - osobiście polecam lekturę: http://conal.net/papers/push-pull-frp/push-pull-frp.pdf)
Dotyczy to głównie monady państwowej. Funkcjonalne programowanie bierne często obejmuje monady, ale zazwyczaj nie jest to prosta monada państwowa. – RD1
Jak już powiedziałem, nie mam doświadczenia w FRP. Niemniej jednak monada państwowa (lub monady) wydaje się być koncepcją, o którą poproszono - wygodnie przechowując i modyfikując dane kontekstowe bez utraty przejrzystości referencyjnej. Jeśli FTP już korzysta z monadycznej infrastruktury, tym lepiej. Transformator stanu monady powinien to zrobić (czy masz na myśli to z * prostym rodzajem *?). Ale bez wyjaśnienia podstaw, informacje te byłyby bezużyteczne! – Dario
Głównym punktem FRP jest umożliwienie definiowania zachowań jako ciągłych funkcji czasu - np. można określić pozycję z kulki pod grawitacją jako z (t) = 9,8 * t * t. Stan monadyczny ma znaczenie tylko dla stanu, który wprowadza dyskretne zmiany - dozwolone są również dyskretne zmiany w FRP, ale są one mniej centralne i często nie pasują do dokładnej formy monady. – RD1