{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeFamilies #-}
module Rattus.ToHaskell
(runTransducer,
runSF,
fromStr,
toStr,
Trans(..)
) where
import System.IO.Unsafe
import Data.IORef
import Rattus.Primitives
import Rattus.Stream
import Rattus.Yampa
data Trans a b = Trans (a -> (b, Trans a b))
runTransducer :: (Str a -> Str b) -> Trans a b
runTransducer tr = Trans run
where run a = unsafePerformIO $ do
asR <- newIORef undefined
as <- unsafeInterleaveIO $ readIORef asR
let b ::: bs = tr (a ::: delay as)
return (b, Trans (run' (adv bs) asR))
run' bs asR a = unsafePerformIO $ do
asR' <- newIORef undefined
as' <- unsafeInterleaveIO $ readIORef asR'
writeIORef asR (a ::: delay as')
let b ::: bs' = bs
return (b, Trans (run' (adv bs') asR'))
runSF :: SF a b -> Trans (a, Double) b
runSF sf = Trans (\(a,t) -> let (s, b) = stepSF sf t a in (b, runSF (adv s)))
toStr :: [a] -> Str a
toStr (x : xs) = x ::: delay (toStr xs)
toStr _ = error "toStr: input terminated"
fromStr :: Str a -> [a]
fromStr (x ::: xs) = x : fromStr (adv xs)