{-# LANGUAGE Trustworthy #-} -- Safe if eliminate GeneralizedNewtypeInstance {-# LANGUAGE Arrows #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE BangPatterns #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Control.Arrow.Machine.Types where import qualified Control.Category as Cat import Data.Profunctor (Profunctor, dimap, rmap) import Control.Arrow import Control.Monad import Control.Monad.Trans import Control.Monad.State import Control.Monad.Reader import Control.Monad.Writer hiding ((<>)) import Control.Monad.Identity import Control.Applicative import Data.Foldable as Fd import Data.Traversable as Tv import Data.Semigroup (Semigroup, (<>)) import Data.Maybe (fromMaybe, isNothing, isJust) import qualified Control.Monad.Trans.Free as F import qualified Control.Monad.Trans.Free.Church as F import Control.Arrow.Machine.ArrowUtil import GHC.Exts (build) -- | To get multiple outputs by one input, the `Phase` parameter is introduced. -- -- Once a value `Feed`ed, the machine is `Sweep`ed until it `Suspend`s. data Phase = Feed | Sweep | Suspend deriving (Eq, Show) instance Monoid Phase where mempty = Sweep mappend Feed _ = Feed mappend _ Feed = Feed mappend Suspend _ = Suspend mappend _ Suspend = Suspend mappend Sweep Sweep = Sweep type ProcType a b c = ProcessA a b c -- | The stream transducer arrow. -- -- To construct `ProcessA` instances, use `Control.Arrow.Machine.Plan.Plan`, -- `arr`, functions declared in `Control.Arrow.Machine.Utils`, -- or arrow combinations of them. -- -- See an introduction at "Control.Arrow.Machine" documentation. data ProcessA a b c = ProcessA { feed :: a b (c, ProcessA a b c), sweep :: a b (Maybe c, ProcessA a b c), suspend :: !(b -> c) } -- For internal use class (Applicative f, Monad f) => ProcessHelper f where step :: ArrowApply a => ProcessA a b c -> a b (f c, ProcessA a b c) helperToMaybe :: f a -> Maybe a weakly :: a -> f a step' :: ArrowApply a => ProcessA a b c -> a (f b) (f c, ProcessA a b c) step' pa = proc hx -> do let mx = helperToMaybe hx maybe (arr $ const (suspend pa <$> hx, pa)) (\x -> proc _ -> step pa -< x) mx -<< ()