[Haskell-cafe] Inputs to classic FRP: unsafeInterleaveIO/unsafePerformIO

Ryan Ingram ryani.spam at gmail.com
Tue Apr 26 04:22:33 CEST 2011


Of course, you could have the 'interpretation' function be non-pure.

For example:

-- Library functions for a hypothetical FRP system
pollEvent :: IO [a] -> Event a
behavior :: a -> Event a -> Behavior a
accumB :: b -> (b -> a -> b) -> Event a -> Behavior b
accumE :: b -> (b -> a -> b) -> Event a -> Event b
union :: Event a -> Event a -> Event a
runFRP :: (a -> IO Bool) -> Behavior a -> IO ()
-- Event & Behavior become instances of Functor & Applicative

-- and now a hypothetical implementation
data Event a where
   Event :: s -- initial state
               -> (s -> IO ([a], s))  -- tick
               -> Event a
data Behavior a = Behavior a (Event a)

pollEvent act = Event () $ \() -> do
     xs <- act
     return (xs, ())

behavior = Behavior

union (Event sL0 tickL) (Event sR0 tickR) = Event (sL0,sR0) tick where
    tick (sL, sR) = do
        (ls, sL') <- tickL sL
        (rs, sR') <- tickR sR
        return (ls ++ rs, (sL', sR'))

accumB b0 f e = Behavior b0 $ accumE b f e

accumE b0 f (Event s0 tickE) = Event (b0, s0) tick where
    tick (b, s) = do
        (as, s') <- tickE s
        let bs = scanl f b as
        return (bs, (last bs, s'))

-- Functor, Applicative instances are pretty easy and left as an exercise

runFRP tick (Behavior b0 (Event s0 e)) = runFRP' b0 s0 where
    runFRP' b s = do
    (bs, s') <- e s0
    let val = last (b:bs)
    k <- tick b
    when k $ runFRP tick (Behavior

    k <- tick b




-- sample application
keypress :: Event Char
keypress = pollEvent getCurrentPressedKeys where
   getCurrentPressedKeys = undefined -- exercise for the reader







On Mon, Apr 25, 2011 at 5:28 PM, Edward Amsden <eca7215 at cs.rit.edu> wrote:

> As far as I can tell, with classic FRP implementations (those which
> use behaviors as a first-class abstraction), the only way to create a
> behavior or
> event based on some external input (for instance keypresses or
> microphone input) is to do something with unsafePerformIO or
> unsafeInterleaveIO. A behavior is a value, which when evaluated at a
> specific time would have to either block its evaluation until input
> could be read, or check the input at that particular time.
>
> Is there any other way of implementing external behaviors besides that?
>
> --
> Edward Amsden
> Student
> Computer Science
> Rochester Institute of Technology
> www.edwardamsden.com
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20110425/fab6bbf5/attachment.htm>


More information about the Haskell-Cafe mailing list