{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}

module Data.Automaton.Recursive where

-- base
import Control.Applicative (Alternative)
import Control.Arrow
import Control.Category
import Prelude hiding (id, (.))

-- transformers
import Control.Monad.Trans.Reader

-- automaton
import Data.Automaton
import Data.Stream.Optimized qualified as StreamOptimized
import Data.Stream.Recursive qualified as StreamRecursive

{- | Automata in direct recursive encoding.

This type is isomorphic to @MSF@ from @dunai@.
-}
newtype Recursive m a b = Recursive {forall (m :: Type -> Type) a b.
Recursive m a b -> Recursive (ReaderT a m) b
getRecursive :: StreamRecursive.Recursive (ReaderT a m) b}
  deriving newtype ((forall a b. (a -> b) -> Recursive m a a -> Recursive m a b)
-> (forall a b. a -> Recursive m a b -> Recursive m a a)
-> Functor (Recursive m a)
forall a b. a -> Recursive m a b -> Recursive m a a
forall a b. (a -> b) -> Recursive m a a -> Recursive m a b
forall (f :: Type -> Type).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
forall (m :: Type -> Type) a a b.
Functor m =>
a -> Recursive m a b -> Recursive m a a
forall (m :: Type -> Type) a a b.
Functor m =>
(a -> b) -> Recursive m a a -> Recursive m a b
$cfmap :: forall (m :: Type -> Type) a a b.
Functor m =>
(a -> b) -> Recursive m a a -> Recursive m a b
fmap :: forall a b. (a -> b) -> Recursive m a a -> Recursive m a b
$c<$ :: forall (m :: Type -> Type) a a b.
Functor m =>
a -> Recursive m a b -> Recursive m a a
<$ :: forall a b. a -> Recursive m a b -> Recursive m a a
Functor, Functor (Recursive m a)
Functor (Recursive m a) =>
(forall a. a -> Recursive m a a)
-> (forall a b.
    Recursive m a (a -> b) -> Recursive m a a -> Recursive m a b)
-> (forall a b c.
    (a -> b -> c)
    -> Recursive m a a -> Recursive m a b -> Recursive m a c)
-> (forall a b.
    Recursive m a a -> Recursive m a b -> Recursive m a b)
-> (forall a b.
    Recursive m a a -> Recursive m a b -> Recursive m a a)
-> Applicative (Recursive m a)
forall a. a -> Recursive m a a
forall a b. Recursive m a a -> Recursive m a b -> Recursive m a a
forall a b. Recursive m a a -> Recursive m a b -> Recursive m a b
forall a b.
Recursive m a (a -> b) -> Recursive m a a -> Recursive m a b
forall a b c.
(a -> b -> c)
-> Recursive m a a -> Recursive m a b -> Recursive m a c
forall (f :: Type -> Type).
Functor f =>
(forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
forall (m :: Type -> Type) a.
Applicative m =>
Functor (Recursive m a)
forall (m :: Type -> Type) a a.
Applicative m =>
a -> Recursive m a a
forall (m :: Type -> Type) a a b.
Applicative m =>
Recursive m a a -> Recursive m a b -> Recursive m a a
forall (m :: Type -> Type) a a b.
Applicative m =>
Recursive m a a -> Recursive m a b -> Recursive m a b
forall (m :: Type -> Type) a a b.
Applicative m =>
Recursive m a (a -> b) -> Recursive m a a -> Recursive m a b
forall (m :: Type -> Type) a a b c.
Applicative m =>
(a -> b -> c)
-> Recursive m a a -> Recursive m a b -> Recursive m a c
$cpure :: forall (m :: Type -> Type) a a.
Applicative m =>
a -> Recursive m a a
pure :: forall a. a -> Recursive m a a
$c<*> :: forall (m :: Type -> Type) a a b.
Applicative m =>
Recursive m a (a -> b) -> Recursive m a a -> Recursive m a b
<*> :: forall a b.
Recursive m a (a -> b) -> Recursive m a a -> Recursive m a b
$cliftA2 :: forall (m :: Type -> Type) a a b c.
Applicative m =>
(a -> b -> c)
-> Recursive m a a -> Recursive m a b -> Recursive m a c
liftA2 :: forall a b c.
(a -> b -> c)
-> Recursive m a a -> Recursive m a b -> Recursive m a c
$c*> :: forall (m :: Type -> Type) a a b.
Applicative m =>
Recursive m a a -> Recursive m a b -> Recursive m a b
*> :: forall a b. Recursive m a a -> Recursive m a b -> Recursive m a b
$c<* :: forall (m :: Type -> Type) a a b.
Applicative m =>
Recursive m a a -> Recursive m a b -> Recursive m a a
<* :: forall a b. Recursive m a a -> Recursive m a b -> Recursive m a a
Applicative, Applicative (Recursive m a)
Applicative (Recursive m a) =>
(forall a. Recursive m a a)
-> (forall a.
    Recursive m a a -> Recursive m a a -> Recursive m a a)
-> (forall a. Recursive m a a -> Recursive m a [a])
-> (forall a. Recursive m a a -> Recursive m a [a])
-> Alternative (Recursive m a)
forall a. Recursive m a a
forall a. Recursive m a a -> Recursive m a [a]
forall a. Recursive m a a -> Recursive m a a -> Recursive m a a
forall (f :: Type -> Type).
Applicative f =>
(forall a. f a)
-> (forall a. f a -> f a -> f a)
-> (forall a. f a -> f [a])
-> (forall a. f a -> f [a])
-> Alternative f
forall (m :: Type -> Type) a.
Alternative m =>
Applicative (Recursive m a)
forall (m :: Type -> Type) a a. Alternative m => Recursive m a a
forall (m :: Type -> Type) a a.
Alternative m =>
Recursive m a a -> Recursive m a [a]
forall (m :: Type -> Type) a a.
Alternative m =>
Recursive m a a -> Recursive m a a -> Recursive m a a
$cempty :: forall (m :: Type -> Type) a a. Alternative m => Recursive m a a
empty :: forall a. Recursive m a a
$c<|> :: forall (m :: Type -> Type) a a.
Alternative m =>
Recursive m a a -> Recursive m a a -> Recursive m a a
<|> :: forall a. Recursive m a a -> Recursive m a a -> Recursive m a a
$csome :: forall (m :: Type -> Type) a a.
Alternative m =>
Recursive m a a -> Recursive m a [a]
some :: forall a. Recursive m a a -> Recursive m a [a]
$cmany :: forall (m :: Type -> Type) a a.
Alternative m =>
Recursive m a a -> Recursive m a [a]
many :: forall a. Recursive m a a -> Recursive m a [a]
Alternative)

instance (Monad m) => Category (Recursive m) where
  id :: forall a. Recursive m a a
id = Automaton m a a -> Recursive m a a
forall (m :: Type -> Type) a b.
Functor m =>
Automaton m a b -> Recursive m a b
toRecursive Automaton m a a
forall a. Automaton m a a
forall {k} (cat :: k -> k -> Type) (a :: k).
Category cat =>
cat a a
id
  Recursive m b c
f1 . :: forall b c a. Recursive m b c -> Recursive m a b -> Recursive m a c
. Recursive m a b
f2 = Automaton m a c -> Recursive m a c
forall (m :: Type -> Type) a b.
Functor m =>
Automaton m a b -> Recursive m a b
toRecursive (Automaton m a c -> Recursive m a c)
-> Automaton m a c -> Recursive m a c
forall a b. (a -> b) -> a -> b
$ Recursive m b c -> Automaton m b c
forall (m :: Type -> Type) a b. Recursive m a b -> Automaton m a b
fromRecursive Recursive m b c
f1 Automaton m b c -> Automaton m a b -> Automaton m a c
forall b c a. Automaton m b c -> Automaton m a b -> Automaton m a c
forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Recursive m a b -> Automaton m a b
forall (m :: Type -> Type) a b. Recursive m a b -> Automaton m a b
fromRecursive Recursive m a b
f2

instance (Monad m) => Arrow (Recursive m) where
  arr :: forall b c. (b -> c) -> Recursive m b c
arr = Automaton m b c -> Recursive m b c
forall (m :: Type -> Type) a b.
Functor m =>
Automaton m a b -> Recursive m a b
toRecursive (Automaton m b c -> Recursive m b c)
-> ((b -> c) -> Automaton m b c) -> (b -> c) -> Recursive m b c
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (b -> c) -> Automaton m b c
forall b c. (b -> c) -> Automaton m b c
forall (a :: Type -> Type -> Type) b c.
Arrow a =>
(b -> c) -> a b c
arr
  first :: forall b c d. Recursive m b c -> Recursive m (b, d) (c, d)
first = Automaton m (b, d) (c, d) -> Recursive m (b, d) (c, d)
forall (m :: Type -> Type) a b.
Functor m =>
Automaton m a b -> Recursive m a b
toRecursive (Automaton m (b, d) (c, d) -> Recursive m (b, d) (c, d))
-> (Recursive m b c -> Automaton m (b, d) (c, d))
-> Recursive m b c
-> Recursive m (b, d) (c, d)
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Automaton m b c -> Automaton m (b, d) (c, d)
forall b c d. Automaton m b c -> Automaton m (b, d) (c, d)
forall (a :: Type -> Type -> Type) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first (Automaton m b c -> Automaton m (b, d) (c, d))
-> (Recursive m b c -> Automaton m b c)
-> Recursive m b c
-> Automaton m (b, d) (c, d)
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Recursive m b c -> Automaton m b c
forall (m :: Type -> Type) a b. Recursive m a b -> Automaton m a b
fromRecursive

toRecursive :: (Functor m) => Automaton m a b -> Recursive m a b
toRecursive :: forall (m :: Type -> Type) a b.
Functor m =>
Automaton m a b -> Recursive m a b
toRecursive (Automaton OptimizedStreamT (ReaderT a m) b
automaton) = Recursive (ReaderT a m) b -> Recursive m a b
forall (m :: Type -> Type) a b.
Recursive (ReaderT a m) b -> Recursive m a b
Recursive (Recursive (ReaderT a m) b -> Recursive m a b)
-> Recursive (ReaderT a m) b -> Recursive m a b
forall a b. (a -> b) -> a -> b
$ OptimizedStreamT (ReaderT a m) b -> Recursive (ReaderT a m) b
forall (m :: Type -> Type) a.
Functor m =>
OptimizedStreamT m a -> Recursive m a
StreamOptimized.toRecursive OptimizedStreamT (ReaderT a m) b
automaton

fromRecursive :: Recursive m a b -> Automaton m a b
fromRecursive :: forall (m :: Type -> Type) a b. Recursive m a b -> Automaton m a b
fromRecursive Recursive {Recursive (ReaderT a m) b
getRecursive :: forall (m :: Type -> Type) a b.
Recursive m a b -> Recursive (ReaderT a m) b
getRecursive :: Recursive (ReaderT a m) b
getRecursive} = OptimizedStreamT (ReaderT a m) b -> Automaton m a b
forall (m :: Type -> Type) a b.
OptimizedStreamT (ReaderT a m) b -> Automaton m a b
Automaton (OptimizedStreamT (ReaderT a m) b -> Automaton m a b)
-> OptimizedStreamT (ReaderT a m) b -> Automaton m a b
forall a b. (a -> b) -> a -> b
$ Recursive (ReaderT a m) b -> OptimizedStreamT (ReaderT a m) b
forall (m :: Type -> Type) a. Recursive m a -> OptimizedStreamT m a
StreamOptimized.fromRecursive Recursive (ReaderT a m) b
getRecursive