Skip to content

Instantly share code, notes, and snippets.

@schrammc
Created May 29, 2015 12:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save schrammc/d2fc0e84b5fd52c148dc to your computer and use it in GitHub Desktop.
Save schrammc/d2fc0e84b5fd52c148dc to your computer and use it in GitHub Desktop.
Minimal FRP example
import FRP.Sodium
import FRP.Sodium.IO
import System.Exit (exitSuccess)
import Control.Applicative ((<$>))
import Control.Monad (forever)
import Control.Concurrent
import Control.Monad
import System.Timeout
main :: IO()
main = do
-- Create a new event and a function to push
-- values into it of type (a -> Reactive a)
(clock,pushClock) <- sync newEvent
(inputEvent,pushInput) <- sync newEvent
counter <- sync $ buildCounter inputEvent
clockThread 2 pushClock
sync $ listen (printCounter counter clock) (id)
gatherStdIn pushInput
buildCounter :: Event Char -> Reactive (Behaviour Int)
buildCounter charEvent =
accum 0 increases
where
increases = (const $ (+1)) <$> charEvent
printCounter :: Behaviour Int -> Event () -> Event (IO ())
printCounter counter clockEvent = counterPrintE `merge` clockPrintE
where
counterChangeE = updates counter
counterPrintE = (\c -> putStrLn $ "\n" ++ (show c)) <$> counterChangeE
clockPrintE = snapshot clockPrintF clockEvent counter
clockPrintF () i = putStrLn $ "\nTimer event: " ++ (show i)
clockThread :: Int -> (() -> Reactive ()) -> IO ThreadId
clockThread sleepS pushE = forkIO $ forever $ do
threadDelay sleepTime
sync $ pushE ()
where
-- Sleep time is in microseconds, but input is in seconds
sleepTime = sleepS * 1000 * 1000
gatherStdIn :: (Char -> Reactive ()) -> IO ()
gatherStdIn pushChar = forever $
getChar >>= (sync . pushChar)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment