-- | Stranded reading frames. module Biobase.Types.ReadingFrame where import Control.Lens hiding (Index) import GHC.Generics hiding (from) import Biobase.Types.Index (Index, toInt0) import Biobase.Types.Strand -- | The Reading frame. Sequence indexing starts at position 1, which starts -- reading frame 1. Reading frame 2 and 3 start at position 2 and 3 -- respectively. newtype ReadingFrame = ReadingFrame { getReadingFrame ∷ Int } deriving (Eq,Ord,Generic,Show) makeWrapped ''ReadingFrame -- | Convert between @+1 ... +3@ and @ReadingFrame@. rf ∷ Prism' Int ReadingFrame {-# Inline rf #-} rf = prism' getReadingFrame $ \k → let ak = abs k in if (ak <= 3 && ak >= 1) then Just (ReadingFrame k) else Nothing -- | A lens for the strand strandRF ∷ Lens' ReadingFrame Strand {-# Inline strandRF #-} strandRF = lens (\(ReadingFrame k) → if k < 0 then MinusStrand else PlusStrand) (\(ReadingFrame k) s → ReadingFrame $ if s == PlusStrand then abs k else (negate $ abs k)) -- | -- -- @pred@ and @succ@ are correct, if the input is a legal 'ReadingFrame'. instance Enum ReadingFrame where {-# Inline toEnum #-} toEnum k = case k^?rf of Just rf → rf ; Nothing → error $ show k ++ " is not a legal reading frame" {-# Inline fromEnum #-} fromEnum = getReadingFrame -- | -- -- TODO should this be a type class, since we might reasonably want to -- construct from a number of possible indices? fromIndex ∷ Index 1 → ReadingFrame {-# Inline fromIndex #-} fromIndex i = ReadingFrame $ (toInt0 i `mod` 3) + 1