neural-0.1.0.0: src/Data/Utils/Stack.hs
{-# OPTIONS_HADDOCK show-extensions #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-|
Module : Data.Utils.Stack
Description : a simple stack monad
Copyright : (c) Lars Brünjes, 2016
License : MIT
Maintainer : brunjlar@gmail.com
Stability : experimental
Portability : portable
This module defines the 'StackT' monad transformer,
which is simply a wrapped state monad whose state is a list.
-}
module Data.Utils.Stack
( StackT
, pop
, peek
, push
, runStackT
, evalStackT
, execStackT
, Stack
, runStack
, evalStack
, execStack
) where
import Control.Monad.Trans.Class (MonadTrans)
import Data.MyPrelude
-- | A computation of type @'StackT' s m a@ has access to a stack of elements of type @s@.
--
newtype StackT s m a = StackT (StateT [s] m a)
deriving (Functor, Applicative, Monad, MonadTrans)
-- | Peeks at the top element of the stack. Returns 'Nothing' if the stack is empty.
--
peek :: Monad m => StackT s m (Maybe s)
peek = do
xs <- StackT get
return $ case xs of
[] -> Nothing
(x : _) -> Just x
-- | Pops the top element from the stack. Returns 'Nothing' if the stack is empty.
--
pop :: Monad m => StackT s m (Maybe s)
pop = do
xs <- StackT get
case xs of
[] -> return Nothing
(x : xs') -> (StackT $ put xs') >> return (Just x)
-- | Pushes a new element onto the stack.
--
push :: Monad m => s -> StackT s m ()
push x = StackT $ modify (x :)
-- | Runs a computation in the @'StackT' s m@ monad.
--
runStackT :: Monad m => StackT s m a -> [s] -> m (a, [s])
runStackT (StackT m) = runStateT m
-- | Evaluates a computation in the @'StackT' s m@ monad.
--
evalStackT :: Monad m => StackT s m a -> [s] -> m a
evalStackT m xs = fst <$> runStackT m xs
-- | Executes a computation in the @'StackT' s m@ monad.
--
execStackT :: Monad m => StackT s m a -> [s] -> m [s]
execStackT m xs = snd <$> runStackT m xs
-- | A pure stack monad.
--
type Stack s = StackT s Identity
-- | Runs a computation in the @'Stack' s@ monad.
--
runStack :: Stack s a -> [s] -> (a, [s])
runStack m xs = runIdentity $ runStackT m xs
-- | Evaluates a computation in the @'Stack' s@ monad.
--
evalStack :: Stack s a -> [s] -> a
evalStack m xs = runIdentity $ evalStackT m xs
-- | Executes a computation in the @'Stack' s@ monad.
--
execStack :: Stack s a -> [s] -> [s]
execStack m xs = runIdentity $ execStackT m xs