{-
Copyright 2009 Mario Blazevic
This file is part of the Streaming Component Combinators (SCC) project.
The SCC project is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
version.
SCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with SCC. If not, see
.
-}
-- | Module "Trampoline" defines the trampoline computations and their basic building blocks.
{-# LANGUAGE TypeFamilies #-}
module Control.Concurrent.SCC.Trampoline where
-- | Suspending monadic computations.
newtype Trampoline s m r = Trampoline {
-- | Run the next step of a `Trampoline` computation.
bounce :: m (TrampolineState s m r)
}
data TrampolineState s m r = Suspend (s (Trampoline s m r))
data Yield x y = Yield x y
data Await x y = Await (x -> y)
data EitherFunctor l r x = LeftF (l x) | RightF (r x)
newtype NestedFunctor l r x = NestedFunctor (l (r x))
data SomeFunctor l r x = LeftSome (l x) | RightSome (r x) | Both (NestedFunctor l r x)
type TryYield x = EitherFunctor (Yield x) (Await Bool)
resolveProducerConsumer :: (s' ~ SomeFunctor (SinkFunctor s a) (SourceFunctor s a))
=> s' (Trampoline s' m (x, y)) -> Trampoline s' m (x, y)
resolveProducerConsumer (LeftSome (RightF (LeftF (Yield _ c)))) = c
resolveProducerConsumer (RightSome (RightF (Await c))) = c Nothing
resolveProducerConsumer (Both (NestedFunctor (RightF (LeftF (Yield x (RightF (Await c))))))) = undefined
type SourceFunctor a x = EitherFunctor a (Await (Maybe x))
type SinkFunctor a x = EitherFunctor a (TryYield x)