-- | Secondary structure: define basepairs as Int-tuples, the three edges, a
-- nucleotide can use for pairing and the cis/trans isomerism. Both edges and
-- cis/trans come with a tag for "unknown".
--
-- Since we often want to make "pairedness" explicit, we have a newtype for
-- this as well.
--
-- TODO set ext-annotations to be (isomerism,edge,edge) and have a asString
-- instance to read "cWW" "tSH" and other notation.

module Biobase.Secondary.Basepair where

import           Data.Aeson
import           Data.Binary
import           Data.Char (toLower, toUpper)
import           Data.Ix (Ix(..))
import           Data.List as L
import           Data.Primitive.Types
import           Data.Serialize (Serialize)
import           Data.Tuple (swap)
import           Data.Vector.Fusion.Stream.Monadic (map,Step(..),flatten)
import           Data.Vector.Unboxed.Deriving
import           GHC.Base (remInt,quotInt)
import           GHC.Generics
import qualified Data.Vector.Generic as VG
import qualified Data.Vector.Generic.Mutable as VGM
import qualified Data.Vector.Unboxed as VU
import           Text.Read

import           Biobase.Types.BioSequence
import           Data.PrimitiveArray hiding (Complement(..),map)

import           Biobase.Primary
import           Biobase.Primary.Nuc.RNA
import           Biobase.Primary.Nuc



-- * Newtype for efficient basepair encoding.

-- | Encode a base pair as a single @Int@.

newtype Basepair = BP { Basepair -> Int
getBP :: Int }
  deriving (Basepair -> Basepair -> Bool
(Basepair -> Basepair -> Bool)
-> (Basepair -> Basepair -> Bool) -> Eq Basepair
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Basepair -> Basepair -> Bool
$c/= :: Basepair -> Basepair -> Bool
== :: Basepair -> Basepair -> Bool
$c== :: Basepair -> Basepair -> Bool
Eq,Eq Basepair
Eq Basepair
-> (Basepair -> Basepair -> Ordering)
-> (Basepair -> Basepair -> Bool)
-> (Basepair -> Basepair -> Bool)
-> (Basepair -> Basepair -> Bool)
-> (Basepair -> Basepair -> Bool)
-> (Basepair -> Basepair -> Basepair)
-> (Basepair -> Basepair -> Basepair)
-> Ord Basepair
Basepair -> Basepair -> Bool
Basepair -> Basepair -> Ordering
Basepair -> Basepair -> Basepair
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Basepair -> Basepair -> Basepair
$cmin :: Basepair -> Basepair -> Basepair
max :: Basepair -> Basepair -> Basepair
$cmax :: Basepair -> Basepair -> Basepair
>= :: Basepair -> Basepair -> Bool
$c>= :: Basepair -> Basepair -> Bool
> :: Basepair -> Basepair -> Bool
$c> :: Basepair -> Basepair -> Bool
<= :: Basepair -> Basepair -> Bool
$c<= :: Basepair -> Basepair -> Bool
< :: Basepair -> Basepair -> Bool
$c< :: Basepair -> Basepair -> Bool
compare :: Basepair -> Basepair -> Ordering
$ccompare :: Basepair -> Basepair -> Ordering
$cp1Ord :: Eq Basepair
Ord,Ord Basepair
Ord Basepair
-> ((Basepair, Basepair) -> [Basepair])
-> ((Basepair, Basepair) -> Basepair -> Int)
-> ((Basepair, Basepair) -> Basepair -> Int)
-> ((Basepair, Basepair) -> Basepair -> Bool)
-> ((Basepair, Basepair) -> Int)
-> ((Basepair, Basepair) -> Int)
-> Ix Basepair
(Basepair, Basepair) -> Int
(Basepair, Basepair) -> [Basepair]
(Basepair, Basepair) -> Basepair -> Bool
(Basepair, Basepair) -> Basepair -> Int
forall a.
Ord a
-> ((a, a) -> [a])
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Bool)
-> ((a, a) -> Int)
-> ((a, a) -> Int)
-> Ix a
unsafeRangeSize :: (Basepair, Basepair) -> Int
$cunsafeRangeSize :: (Basepair, Basepair) -> Int
rangeSize :: (Basepair, Basepair) -> Int
$crangeSize :: (Basepair, Basepair) -> Int
inRange :: (Basepair, Basepair) -> Basepair -> Bool
$cinRange :: (Basepair, Basepair) -> Basepair -> Bool
unsafeIndex :: (Basepair, Basepair) -> Basepair -> Int
$cunsafeIndex :: (Basepair, Basepair) -> Basepair -> Int
index :: (Basepair, Basepair) -> Basepair -> Int
$cindex :: (Basepair, Basepair) -> Basepair -> Int
range :: (Basepair, Basepair) -> [Basepair]
$crange :: (Basepair, Basepair) -> [Basepair]
$cp1Ix :: Ord Basepair
Ix,(forall x. Basepair -> Rep Basepair x)
-> (forall x. Rep Basepair x -> Basepair) -> Generic Basepair
forall x. Rep Basepair x -> Basepair
forall x. Basepair -> Rep Basepair x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Basepair x -> Basepair
$cfrom :: forall x. Basepair -> Rep Basepair x
Generic)

derivingUnbox "Basepair"
  [t| Basepair -> Int |] [| getBP |] [| BP |]

instance Binary    Basepair
instance Serialize Basepair
instance FromJSON  Basepair
instance ToJSON    Basepair

instance Index Basepair where
  newtype LimitType Basepair = LtBP Basepair

instance IndexStream z => IndexStream (z:.Basepair) where
  streamUp :: LimitType (z :. Basepair)
-> LimitType (z :. Basepair) -> Stream m (z :. Basepair)
streamUp (ls:..LtBP (BP l)) (hs:..LtBP (BP h)) = (z -> m (z, Int))
-> ((z, Int) -> m (Step (z, Int) (z :. Basepair)))
-> Stream m z
-> Stream m (z :. Basepair)
forall (m :: * -> *) a s b.
Monad m =>
(a -> m s) -> (s -> m (Step s b)) -> Stream m a -> Stream m b
flatten z -> m (z, Int)
mk (z, Int) -> m (Step (z, Int) (z :. Basepair))
step (Stream m z -> Stream m (z :. Basepair))
-> Stream m z -> Stream m (z :. Basepair)
forall a b. (a -> b) -> a -> b
$ LimitType z -> LimitType z -> Stream m z
forall i (m :: * -> *).
(IndexStream i, Monad m) =>
LimitType i -> LimitType i -> Stream m i
streamUp LimitType z
ls LimitType z
hs
    where mk :: z -> m (z, Int)
mk z
z = (z, Int) -> m (z, Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (z
z,Int
l)
          step :: (z, Int) -> m (Step (z, Int) (z :. Basepair))
step (z
z,Int
k)
            | Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
h     = Step (z, Int) (z :. Basepair) -> m (Step (z, Int) (z :. Basepair))
forall (m :: * -> *) a. Monad m => a -> m a
return (Step (z, Int) (z :. Basepair)
 -> m (Step (z, Int) (z :. Basepair)))
-> Step (z, Int) (z :. Basepair)
-> m (Step (z, Int) (z :. Basepair))
forall a b. (a -> b) -> a -> b
$ Step (z, Int) (z :. Basepair)
forall s a. Step s a
Done
            | Bool
otherwise = Step (z, Int) (z :. Basepair) -> m (Step (z, Int) (z :. Basepair))
forall (m :: * -> *) a. Monad m => a -> m a
return (Step (z, Int) (z :. Basepair)
 -> m (Step (z, Int) (z :. Basepair)))
-> Step (z, Int) (z :. Basepair)
-> m (Step (z, Int) (z :. Basepair))
forall a b. (a -> b) -> a -> b
$ (z :. Basepair) -> (z, Int) -> Step (z, Int) (z :. Basepair)
forall a s. a -> s -> Step s a
Yield (z
zz -> Basepair -> z :. Basepair
forall a b. a -> b -> a :. b
:.Int -> Basepair
BP Int
k) (z
z,Int
kInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
          {-# Inline [0] mk   #-}
          {-# Inline [0] step #-}
  {-# Inline streamUp #-}
  streamDown :: LimitType (z :. Basepair)
-> LimitType (z :. Basepair) -> Stream m (z :. Basepair)
streamDown (ls:..LtBP (BP l)) (hs:..LtBP (BP h)) = (z -> m (z, Int))
-> ((z, Int) -> m (Step (z, Int) (z :. Basepair)))
-> Stream m z
-> Stream m (z :. Basepair)
forall (m :: * -> *) a s b.
Monad m =>
(a -> m s) -> (s -> m (Step s b)) -> Stream m a -> Stream m b
flatten z -> m (z, Int)
mk (z, Int) -> m (Step (z, Int) (z :. Basepair))
step (Stream m z -> Stream m (z :. Basepair))
-> Stream m z -> Stream m (z :. Basepair)
forall a b. (a -> b) -> a -> b
$ LimitType z -> LimitType z -> Stream m z
forall i (m :: * -> *).
(IndexStream i, Monad m) =>
LimitType i -> LimitType i -> Stream m i
streamDown LimitType z
ls LimitType z
hs
    where mk :: z -> m (z, Int)
mk z
z = (z, Int) -> m (z, Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (z
z,Int
h)
          step :: (z, Int) -> m (Step (z, Int) (z :. Basepair))
step (z
z,Int
k)
            | Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
l     = Step (z, Int) (z :. Basepair) -> m (Step (z, Int) (z :. Basepair))
forall (m :: * -> *) a. Monad m => a -> m a
return (Step (z, Int) (z :. Basepair)
 -> m (Step (z, Int) (z :. Basepair)))
-> Step (z, Int) (z :. Basepair)
-> m (Step (z, Int) (z :. Basepair))
forall a b. (a -> b) -> a -> b
$ Step (z, Int) (z :. Basepair)
forall s a. Step s a
Done
            | Bool
otherwise = Step (z, Int) (z :. Basepair) -> m (Step (z, Int) (z :. Basepair))
forall (m :: * -> *) a. Monad m => a -> m a
return (Step (z, Int) (z :. Basepair)
 -> m (Step (z, Int) (z :. Basepair)))
-> Step (z, Int) (z :. Basepair)
-> m (Step (z, Int) (z :. Basepair))
forall a b. (a -> b) -> a -> b
$ (z :. Basepair) -> (z, Int) -> Step (z, Int) (z :. Basepair)
forall a s. a -> s -> Step s a
Yield (z
zz -> Basepair -> z :. Basepair
forall a b. a -> b -> a :. b
:.Int -> Basepair
BP Int
k) (z
z,Int
kInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
          {-# Inline [0] mk   #-}
          {-# Inline [0] step #-}
  {-# Inline streamDown #-}

instance IndexStream Basepair

pattern $bAA :: Basepair
$mAA :: forall r. Basepair -> (Void# -> r) -> (Void# -> r) -> r
AA   = BP  0
pattern $bAC :: Basepair
$mAC :: forall r. Basepair -> (Void# -> r) -> (Void# -> r) -> r
AC   = BP  1
pattern $bAG :: Basepair
$mAG :: forall r. Basepair -> (Void# -> r) -> (Void# -> r) -> r
AG   = BP  2
pattern $bAU :: Basepair
$mAU :: forall r. Basepair -> (Void# -> r) -> (Void# -> r) -> r
AU   = BP  3
pattern $bCA :: Basepair
$mCA :: forall r. Basepair -> (Void# -> r) -> (Void# -> r) -> r
CA   = BP  4
pattern $bCC :: Basepair
$mCC :: forall r. Basepair -> (Void# -> r) -> (Void# -> r) -> r
CC   = BP  5
pattern $bCG :: Basepair
$mCG :: forall r. Basepair -> (Void# -> r) -> (Void# -> r) -> r
CG   = BP  6
pattern $bCU :: Basepair
$mCU :: forall r. Basepair -> (Void# -> r) -> (Void# -> r) -> r
CU   = BP  7
pattern $bGA :: Basepair
$mGA :: forall r. Basepair -> (Void# -> r) -> (Void# -> r) -> r
GA   = BP  8
pattern $bGC :: Basepair
$mGC :: forall r. Basepair -> (Void# -> r) -> (Void# -> r) -> r
GC   = BP  9
pattern $bGG :: Basepair
$mGG :: forall r. Basepair -> (Void# -> r) -> (Void# -> r) -> r
GG   = BP 10
pattern $bGU :: Basepair
$mGU :: forall r. Basepair -> (Void# -> r) -> (Void# -> r) -> r
GU   = BP 11
pattern $bUA :: Basepair
$mUA :: forall r. Basepair -> (Void# -> r) -> (Void# -> r) -> r
UA   = BP 12
pattern $bUC :: Basepair
$mUC :: forall r. Basepair -> (Void# -> r) -> (Void# -> r) -> r
UC   = BP 13
pattern $bUG :: Basepair
$mUG :: forall r. Basepair -> (Void# -> r) -> (Void# -> r) -> r
UG   = BP 14
pattern $bUU :: Basepair
$mUU :: forall r. Basepair -> (Void# -> r) -> (Void# -> r) -> r
UU   = BP 15
pattern $bNS :: Basepair
$mNS :: forall r. Basepair -> (Void# -> r) -> (Void# -> r) -> r
NS   = BP 16
pattern $bNoBP :: Basepair
$mNoBP :: forall r. Basepair -> (Void# -> r) -> (Void# -> r) -> r
NoBP = BP 17

{-
class MkBasepair a where
  mkBasepair :: a -> Basepair
  fromBasepair :: Basepair -> a

-- | If we get a "legal" base pair, we just create it, all other
-- combinations yield 'NoBP'. Non-standard base pairs have to be created
-- explicitly using @NS@. When going back to @a@, non-standard and no pair
-- yield @(N,N)@.

instance MkBasepair (Letter RNA,Letter RNA) where
  mkBasepair (l,r)
    | l >= A && l <= U && r >= A && r <= U
    = BP $ 4 * getLetter l + getLetter r
    | otherwise = NoBP
  fromBasepair k
    | k == NoBP || k == NS = (N,N)
    | otherwise = let (l,r) = getBP k `divMod` 4 in (Letter l, Letter r)
  {-# Inline mkBasepair #-}
  {-# Inline fromBasepair #-}
-}


-- * Newtypes for extended secondary structures

-- ** Encode which of three edges is engaged in base pairing

-- | Each nucleotide in a pair may be paired using one of three edges:
-- watson-crick, sugar, or hoogsteen.

newtype Edge = Edge {Edge -> Int
unEdge :: Int}
  deriving (Edge -> Edge -> Bool
(Edge -> Edge -> Bool) -> (Edge -> Edge -> Bool) -> Eq Edge
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Edge -> Edge -> Bool
$c/= :: Edge -> Edge -> Bool
== :: Edge -> Edge -> Bool
$c== :: Edge -> Edge -> Bool
Eq,Eq Edge
Eq Edge
-> (Edge -> Edge -> Ordering)
-> (Edge -> Edge -> Bool)
-> (Edge -> Edge -> Bool)
-> (Edge -> Edge -> Bool)
-> (Edge -> Edge -> Bool)
-> (Edge -> Edge -> Edge)
-> (Edge -> Edge -> Edge)
-> Ord Edge
Edge -> Edge -> Bool
Edge -> Edge -> Ordering
Edge -> Edge -> Edge
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Edge -> Edge -> Edge
$cmin :: Edge -> Edge -> Edge
max :: Edge -> Edge -> Edge
$cmax :: Edge -> Edge -> Edge
>= :: Edge -> Edge -> Bool
$c>= :: Edge -> Edge -> Bool
> :: Edge -> Edge -> Bool
$c> :: Edge -> Edge -> Bool
<= :: Edge -> Edge -> Bool
$c<= :: Edge -> Edge -> Bool
< :: Edge -> Edge -> Bool
$c< :: Edge -> Edge -> Bool
compare :: Edge -> Edge -> Ordering
$ccompare :: Edge -> Edge -> Ordering
$cp1Ord :: Eq Edge
Ord,Ord Edge
Ord Edge
-> ((Edge, Edge) -> [Edge])
-> ((Edge, Edge) -> Edge -> Int)
-> ((Edge, Edge) -> Edge -> Int)
-> ((Edge, Edge) -> Edge -> Bool)
-> ((Edge, Edge) -> Int)
-> ((Edge, Edge) -> Int)
-> Ix Edge
(Edge, Edge) -> Int
(Edge, Edge) -> [Edge]
(Edge, Edge) -> Edge -> Bool
(Edge, Edge) -> Edge -> Int
forall a.
Ord a
-> ((a, a) -> [a])
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Bool)
-> ((a, a) -> Int)
-> ((a, a) -> Int)
-> Ix a
unsafeRangeSize :: (Edge, Edge) -> Int
$cunsafeRangeSize :: (Edge, Edge) -> Int
rangeSize :: (Edge, Edge) -> Int
$crangeSize :: (Edge, Edge) -> Int
inRange :: (Edge, Edge) -> Edge -> Bool
$cinRange :: (Edge, Edge) -> Edge -> Bool
unsafeIndex :: (Edge, Edge) -> Edge -> Int
$cunsafeIndex :: (Edge, Edge) -> Edge -> Int
index :: (Edge, Edge) -> Edge -> Int
$cindex :: (Edge, Edge) -> Edge -> Int
range :: (Edge, Edge) -> [Edge]
$crange :: (Edge, Edge) -> [Edge]
$cp1Ix :: Ord Edge
Ix,(forall x. Edge -> Rep Edge x)
-> (forall x. Rep Edge x -> Edge) -> Generic Edge
forall x. Rep Edge x -> Edge
forall x. Edge -> Rep Edge x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Edge x -> Edge
$cfrom :: forall x. Edge -> Rep Edge x
Generic)

pattern $bW :: Edge
$mW :: forall r. Edge -> (Void# -> r) -> (Void# -> r) -> r
W = Edge 0
pattern $bS :: Edge
$mS :: forall r. Edge -> (Void# -> r) -> (Void# -> r) -> r
S = Edge 1
pattern $bH :: Edge
$mH :: forall r. Edge -> (Void# -> r) -> (Void# -> r) -> r
H = Edge 2

instance Binary    Edge
instance Serialize Edge
instance FromJSON  Edge
instance ToJSON    Edge



-- | Human-readable Show instance.

instance Show Edge where
  show :: Edge -> String
show Edge
H = String
"H"
  show Edge
S = String
"S"
  show Edge
W = String
"W"

-- | Human-readable Read instance.

instance Read Edge where
  readPrec :: ReadPrec Edge
readPrec = ReadPrec Edge -> ReadPrec Edge
forall a. ReadPrec a -> ReadPrec a
parens (ReadPrec Edge -> ReadPrec Edge) -> ReadPrec Edge -> ReadPrec Edge
forall a b. (a -> b) -> a -> b
$ do
    Ident String
s <- ReadPrec Lexeme
lexP
    Edge -> ReadPrec Edge
forall (m :: * -> *) a. Monad m => a -> m a
return (Edge -> ReadPrec Edge) -> Edge -> ReadPrec Edge
forall a b. (a -> b) -> a -> b
$ case String
s of
      String
"H" -> Edge
H
      String
"S" -> Edge
S
      String
"W" -> Edge
W
      String
_   -> String -> Edge
forall a. HasCallStack => String -> a
error (String -> Edge) -> String -> Edge
forall a b. (a -> b) -> a -> b
$ String
"read Edge: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
s

instance Bounded Edge where
  minBound :: Edge
minBound = Edge
W
  maxBound :: Edge
maxBound = Edge
H

instance Enum Edge where
  toEnum :: Int -> Edge
toEnum   = Int -> Edge
Edge
  fromEnum :: Edge -> Int
fromEnum = Edge -> Int
unEdge

derivingUnbox "Edge"
  [t| Edge -> Int |] [| unEdge |] [| Edge |]

-- ** Is the base pair in cis or trans configuration

-- | Nucleotides in a pairing may be in the cis(==?) or trans(==?) state.

newtype CTisomerism = CT {CTisomerism -> Int
unCT :: Int}
  deriving (CTisomerism -> CTisomerism -> Bool
(CTisomerism -> CTisomerism -> Bool)
-> (CTisomerism -> CTisomerism -> Bool) -> Eq CTisomerism
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CTisomerism -> CTisomerism -> Bool
$c/= :: CTisomerism -> CTisomerism -> Bool
== :: CTisomerism -> CTisomerism -> Bool
$c== :: CTisomerism -> CTisomerism -> Bool
Eq,Eq CTisomerism
Eq CTisomerism
-> (CTisomerism -> CTisomerism -> Ordering)
-> (CTisomerism -> CTisomerism -> Bool)
-> (CTisomerism -> CTisomerism -> Bool)
-> (CTisomerism -> CTisomerism -> Bool)
-> (CTisomerism -> CTisomerism -> Bool)
-> (CTisomerism -> CTisomerism -> CTisomerism)
-> (CTisomerism -> CTisomerism -> CTisomerism)
-> Ord CTisomerism
CTisomerism -> CTisomerism -> Bool
CTisomerism -> CTisomerism -> Ordering
CTisomerism -> CTisomerism -> CTisomerism
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: CTisomerism -> CTisomerism -> CTisomerism
$cmin :: CTisomerism -> CTisomerism -> CTisomerism
max :: CTisomerism -> CTisomerism -> CTisomerism
$cmax :: CTisomerism -> CTisomerism -> CTisomerism
>= :: CTisomerism -> CTisomerism -> Bool
$c>= :: CTisomerism -> CTisomerism -> Bool
> :: CTisomerism -> CTisomerism -> Bool
$c> :: CTisomerism -> CTisomerism -> Bool
<= :: CTisomerism -> CTisomerism -> Bool
$c<= :: CTisomerism -> CTisomerism -> Bool
< :: CTisomerism -> CTisomerism -> Bool
$c< :: CTisomerism -> CTisomerism -> Bool
compare :: CTisomerism -> CTisomerism -> Ordering
$ccompare :: CTisomerism -> CTisomerism -> Ordering
$cp1Ord :: Eq CTisomerism
Ord,Ord CTisomerism
Ord CTisomerism
-> ((CTisomerism, CTisomerism) -> [CTisomerism])
-> ((CTisomerism, CTisomerism) -> CTisomerism -> Int)
-> ((CTisomerism, CTisomerism) -> CTisomerism -> Int)
-> ((CTisomerism, CTisomerism) -> CTisomerism -> Bool)
-> ((CTisomerism, CTisomerism) -> Int)
-> ((CTisomerism, CTisomerism) -> Int)
-> Ix CTisomerism
(CTisomerism, CTisomerism) -> Int
(CTisomerism, CTisomerism) -> [CTisomerism]
(CTisomerism, CTisomerism) -> CTisomerism -> Bool
(CTisomerism, CTisomerism) -> CTisomerism -> Int
forall a.
Ord a
-> ((a, a) -> [a])
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Bool)
-> ((a, a) -> Int)
-> ((a, a) -> Int)
-> Ix a
unsafeRangeSize :: (CTisomerism, CTisomerism) -> Int
$cunsafeRangeSize :: (CTisomerism, CTisomerism) -> Int
rangeSize :: (CTisomerism, CTisomerism) -> Int
$crangeSize :: (CTisomerism, CTisomerism) -> Int
inRange :: (CTisomerism, CTisomerism) -> CTisomerism -> Bool
$cinRange :: (CTisomerism, CTisomerism) -> CTisomerism -> Bool
unsafeIndex :: (CTisomerism, CTisomerism) -> CTisomerism -> Int
$cunsafeIndex :: (CTisomerism, CTisomerism) -> CTisomerism -> Int
index :: (CTisomerism, CTisomerism) -> CTisomerism -> Int
$cindex :: (CTisomerism, CTisomerism) -> CTisomerism -> Int
range :: (CTisomerism, CTisomerism) -> [CTisomerism]
$crange :: (CTisomerism, CTisomerism) -> [CTisomerism]
$cp1Ix :: Ord CTisomerism
Ix,(forall x. CTisomerism -> Rep CTisomerism x)
-> (forall x. Rep CTisomerism x -> CTisomerism)
-> Generic CTisomerism
forall x. Rep CTisomerism x -> CTisomerism
forall x. CTisomerism -> Rep CTisomerism x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep CTisomerism x -> CTisomerism
$cfrom :: forall x. CTisomerism -> Rep CTisomerism x
Generic)

pattern $bCis :: CTisomerism
$mCis :: forall r. CTisomerism -> (Void# -> r) -> (Void# -> r) -> r
Cis = CT 0
pattern $bTrn :: CTisomerism
$mTrn :: forall r. CTisomerism -> (Void# -> r) -> (Void# -> r) -> r
Trn = CT 1

instance Binary    CTisomerism
instance Serialize CTisomerism
instance FromJSON  CTisomerism
instance ToJSON    CTisomerism


-- | Human-readable Show instance.

instance Show CTisomerism where
  show :: CTisomerism -> String
show CTisomerism
Cis = String
"C"
  show CTisomerism
Trn = String
"T"

-- | Human-readable Read instance.

instance Read CTisomerism where
  readPrec :: ReadPrec CTisomerism
readPrec = ReadPrec CTisomerism -> ReadPrec CTisomerism
forall a. ReadPrec a -> ReadPrec a
parens (ReadPrec CTisomerism -> ReadPrec CTisomerism)
-> ReadPrec CTisomerism -> ReadPrec CTisomerism
forall a b. (a -> b) -> a -> b
$ do
    Ident String
s <- ReadPrec Lexeme
lexP
    CTisomerism -> ReadPrec CTisomerism
forall (m :: * -> *) a. Monad m => a -> m a
return (CTisomerism -> ReadPrec CTisomerism)
-> CTisomerism -> ReadPrec CTisomerism
forall a b. (a -> b) -> a -> b
$ case String
s of
      String
"C" -> CTisomerism
Cis
      String
"T" -> CTisomerism
Trn
      String
_   -> String -> CTisomerism
forall a. HasCallStack => String -> a
error (String -> CTisomerism) -> String -> CTisomerism
forall a b. (a -> b) -> a -> b
$ String
"read CTisomerism: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
s

instance Bounded CTisomerism where
  minBound :: CTisomerism
minBound = CTisomerism
Cis
  maxBound :: CTisomerism
maxBound = CTisomerism
Trn

instance Enum CTisomerism where
  toEnum :: Int -> CTisomerism
toEnum   = Int -> CTisomerism
CT
  fromEnum :: CTisomerism -> Int
fromEnum = CTisomerism -> Int
unCT

derivingUnbox "CTisomerism"
  [t| CTisomerism -> Int |] [| unCT |] [| CT |]



-- * Types

-- | A basepair is simply a pair of Ints which are 0-indexing a sequence.

type PairIdx = (Int,Int)

-- | A pair as a tuple containing 'Nuc's.

type Pair n = (Letter RNA n, Letter RNA n)

-- | Annotation for a basepair.

type ExtPairAnnotation = (CTisomerism,Edge,Edge)

-- | An extended basepair is a basepair, annotated with edge and CTisomerism.

type ExtPairIdx = (PairIdx,ExtPairAnnotation)

-- | An extended basepair, with nucleotides an annotation.

type ExtPair n = (Pair n, ExtPairAnnotation)



-- * little helpers

pattern $bCHH :: (CTisomerism, Edge, Edge)
$mCHH :: forall r.
(CTisomerism, Edge, Edge) -> (Void# -> r) -> (Void# -> r) -> r
CHH = (Cis,H,H)
pattern $bCHS :: (CTisomerism, Edge, Edge)
$mCHS :: forall r.
(CTisomerism, Edge, Edge) -> (Void# -> r) -> (Void# -> r) -> r
CHS = (Cis,H,S)
pattern $bCHW :: (CTisomerism, Edge, Edge)
$mCHW :: forall r.
(CTisomerism, Edge, Edge) -> (Void# -> r) -> (Void# -> r) -> r
CHW = (Cis,H,W)
pattern $bCSH :: (CTisomerism, Edge, Edge)
$mCSH :: forall r.
(CTisomerism, Edge, Edge) -> (Void# -> r) -> (Void# -> r) -> r
CSH = (Cis,S,H)
pattern $bCSS :: (CTisomerism, Edge, Edge)
$mCSS :: forall r.
(CTisomerism, Edge, Edge) -> (Void# -> r) -> (Void# -> r) -> r
CSS = (Cis,S,S)
pattern $bCSW :: (CTisomerism, Edge, Edge)
$mCSW :: forall r.
(CTisomerism, Edge, Edge) -> (Void# -> r) -> (Void# -> r) -> r
CSW = (Cis,S,W)
pattern $bCWH :: (CTisomerism, Edge, Edge)
$mCWH :: forall r.
(CTisomerism, Edge, Edge) -> (Void# -> r) -> (Void# -> r) -> r
CWH = (Cis,W,H)
pattern $bCWS :: (CTisomerism, Edge, Edge)
$mCWS :: forall r.
(CTisomerism, Edge, Edge) -> (Void# -> r) -> (Void# -> r) -> r
CWS = (Cis,W,S)
pattern $bCWW :: (CTisomerism, Edge, Edge)
$mCWW :: forall r.
(CTisomerism, Edge, Edge) -> (Void# -> r) -> (Void# -> r) -> r
CWW = (Cis,W,W)

pattern $bTHH :: (CTisomerism, Edge, Edge)
$mTHH :: forall r.
(CTisomerism, Edge, Edge) -> (Void# -> r) -> (Void# -> r) -> r
THH = (Trn,H,H)
pattern $bTHS :: (CTisomerism, Edge, Edge)
$mTHS :: forall r.
(CTisomerism, Edge, Edge) -> (Void# -> r) -> (Void# -> r) -> r
THS = (Trn,H,S)
pattern $bTHW :: (CTisomerism, Edge, Edge)
$mTHW :: forall r.
(CTisomerism, Edge, Edge) -> (Void# -> r) -> (Void# -> r) -> r
THW = (Trn,H,W)
pattern $bTSH :: (CTisomerism, Edge, Edge)
$mTSH :: forall r.
(CTisomerism, Edge, Edge) -> (Void# -> r) -> (Void# -> r) -> r
TSH = (Trn,S,H)
pattern $bTSS :: (CTisomerism, Edge, Edge)
$mTSS :: forall r.
(CTisomerism, Edge, Edge) -> (Void# -> r) -> (Void# -> r) -> r
TSS = (Trn,S,S)
pattern $bTSW :: (CTisomerism, Edge, Edge)
$mTSW :: forall r.
(CTisomerism, Edge, Edge) -> (Void# -> r) -> (Void# -> r) -> r
TSW = (Trn,S,W)
pattern $bTWH :: (CTisomerism, Edge, Edge)
$mTWH :: forall r.
(CTisomerism, Edge, Edge) -> (Void# -> r) -> (Void# -> r) -> r
TWH = (Trn,W,H)
pattern $bTWS :: (CTisomerism, Edge, Edge)
$mTWS :: forall r.
(CTisomerism, Edge, Edge) -> (Void# -> r) -> (Void# -> r) -> r
TWS = (Trn,W,S)
pattern $bTWW :: (CTisomerism, Edge, Edge)
$mTWW :: forall r.
(CTisomerism, Edge, Edge) -> (Void# -> r) -> (Void# -> r) -> r
TWW = (Trn,W,W)