module Control.Observable.Usage.Heartbeat (alive) where
import "base" Control.Applicative ((*>), pure)
import "base" Control.Concurrent (threadDelay)
import "base" Control.Monad ((>>=))
import "base" Data.Either (either)
import "base" Data.Function (($), (.), const)
import "base" Data.Int (Int)
import "base" System.IO (IO)
import "async" Control.Concurrent.Async (race)
import Control.Observable (Observable, obs, notify)
data Beaten a = Alive a | Dead
alive :: Int -> Observable IO a r -> (a -> IO r) -> IO (Beaten r)
alive limit r f = race (threadDelay limit) (notify r f)
>>= either (const . pure $ Dead) ((*>) (alive limit r f) . pure . Alive)