module Data.Order.Element.Representation (
ElementRep (ElementRep),
newMinimum,
newMaximum,
newAfter,
newBefore
) where
import Control.Monad.ST
import Data.Order.Representation
import Data.Order.Algorithm.Raw (RawOrder, RawElement, RawAlgorithm)
import qualified Data.Order.Algorithm.Raw as Raw
import Data.Order.Gate
import Data.IORef
import System.IO.Unsafe
import GHC.IORef (IORef (IORef))
data ElementRep o e = ElementRep (RawAlgorithm RealWorld o e)
(Gate o)
(RawElement RealWorld e)
instance Eq (ElementRep o e) where
ElementRep _ _ rawElem1 == ElementRep _ _ rawElem2 = rawElem1 == rawElem2
instance Ord (ElementRep o e) where
compare (ElementRep rawAlg gate rawElem1)
(ElementRep _ _ rawElem2) = ordering where
ordering = unsafePerformIO $
withRawOrder gate $ \ rawOrder ->
stToIO $
Raw.compareElements rawAlg rawElem1 rawElem2 rawOrder
newMinimum :: OrderRep o e -> IO (ElementRep o e)
newMinimum = fromRawNew Raw.newMinimum
newMaximum :: OrderRep o e -> IO (ElementRep o e)
newMaximum = fromRawNew Raw.newMaximum
newAfter :: ElementRep o e -> OrderRep o e -> IO (ElementRep o e)
newAfter = fromRawNewNeighbor Raw.newAfter
newBefore :: ElementRep o e -> OrderRep o e -> IO (ElementRep o e)
newBefore = fromRawNewNeighbor Raw.newBefore
fromRawNewNeighbor :: (RawAlgorithm RealWorld o e ->
RawElement RealWorld e ->
RawOrder RealWorld o ->
ST RealWorld (RawElement RealWorld e))
-> ElementRep o e
-> OrderRep o e
-> IO (ElementRep o e)
fromRawNewNeighbor rawNewNeighbor (ElementRep _ _ rawElem) = fromRawNew rawNew where
rawNew rawAlg = rawNewNeighbor rawAlg rawElem
fromRawNew :: (RawAlgorithm RealWorld o e ->
RawOrder RealWorld o ->
ST RealWorld (RawElement RealWorld e))
-> OrderRep o e
-> IO (ElementRep o e)
fromRawNew rawNew (OrderRep rawAlg gate) = withRawOrder gate $ \ rawOrder -> do
rawElem <- stToIO $ rawNew rawAlg rawOrder
mkWeakIORef (IORef rawElem)
(withRawOrder gate $ \ rawOrder ->
stToIO $
Raw.delete rawAlg rawElem rawOrder)
return (ElementRep rawAlg gate rawElem)