module Data.Stack.UniqueOrdered where
import Data.Foldable (Foldable (foldl))
import Data.Traversable (Traversable ())
import Data.Monoid (Monoid (mempty, mappend))
import Control.Monad (Monad ((>>=), return))
import Control.Applicative (Applicative (), pure, (<*>))
import Prelude (flip, ($), tail, (.), Eq ((==)), Show (), Ord ((>),(<)), Functor (), fmap)
class (Foldable stack) =>UOStack (stack :: * -> *) where
insert ::(Ord a, Eq a) =>a ->stack a ->stack a
insert = flip into
into ::(Ord a, Eq a) =>stack a ->a ->stack a
into = flip insert
pop ::(Ord a, Eq a) =>stack a ->stack a
inserts ::(Ord a, Eq a) =>[a] ->stack a ->stack a
inserts = flip intos
intos ::(Ord a, Eq a) =>stack a ->[a] ->stack a
intos = foldl into
merge ::(Ord a, Eq a) =>stack a ->stack a ->stack a
merge = foldl into
newtype Asc a = Asc {unAsc ::[a]}
deriving (Show, Eq, Functor, Foldable, Traversable)
instance Monad Asc where
return = Asc . return
(Asc xs) >>= f = Asc $ xs >>= (unAsc . f)
instance (Ord a) =>Monoid (Asc a) where
mempty = Asc []
(Asc xs) `mappend` (Asc ys) = intos (Asc []) $ xs `mappend` ys
newtype Des a = Des {unDes ::[a]}
deriving (Show, Eq, Functor, Foldable, Traversable)
instance Monad Des where
return = Des . return
(Des xs) >>= f = Des $ xs >>= (unDes . f)
instance (Ord a) =>Monoid (Des a) where
mempty = Des []
(Des xs) `mappend` (Des ys) = intos (Des []) $ xs `mappend` ys
instance UOStack Asc where
insert a (Asc []) = Asc [a]
insert a (Asc xss@(x:xs)) | a < x = Asc (a:xss)
| a ==x = Asc xss
| a > x = Asc $ x : (unAsc $ insert a $ Asc xs)
pop (Asc xs) = Asc (tail xs)
instance UOStack Des where
insert a (Des []) = Des [a]
insert a (Des xss@(x:xs)) | a > x = Des (a:xss)
| a ==x = Des xss
| a < x = Des $ x : (unDes $ insert a $ Des xs)
pop (Des xs) = Des (tail xs)