{-# LANGUAGE GADTs #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE FlexibleContexts #-} module Bio.Utils.Types ( Sorted , ordering , fromSorted , toSorted , unsafeToSorted ) where import qualified Data.Foldable as F import Data.Ord () data Sorted f a where Sorted :: (F.Foldable f, Ord a) => { ordering :: !Ordering , fromSorted :: !(f a) } -> Sorted f a deriving instance Show (f a) => Show (Sorted f a) -- | if the data has been sorted, wrap it into Sorted type toSorted :: (F.Foldable f, Ord a) => f a -> Sorted f a toSorted xs = Sorted o xs where o = snd . F.foldl' g (const EQ, EQ) $ xs g (func, ord) x | ord == EQ = (compare x, ord') | ord' == ord || ord' == EQ = (compare x, ord) | otherwise = error "data is not sorted" where ord' = func x unsafeToSorted :: (F.Foldable f, Ord a) => Ordering -> f a -> Sorted f a unsafeToSorted = Sorted