{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ViewPatterns #-}
module Bio.Sequence.Functions.Sequence
( drop
, getRange, unsafeGetRange
, length, null
, reverse
, tail
, take
, toList
, (!), (!?)
) where
import Control.Lens
import Control.Monad.Except (MonadError, throwError)
import qualified Data.Foldable as F (length, null, toList)
import qualified Data.List as L (drop, take)
import Data.Maybe (fromMaybe)
import Data.Text (Text)
import qualified Data.Vector as V
import Prelude hiding (drop, length, null, reverse, tail, take)
import Bio.NucleicAcid.Nucleotide (Complementary (..))
import Bio.Sequence.Class (ContainsNoMarking, IsSequence (..), _sequenceInner, markings,
sequ, weights)
import Bio.Sequence.Range (Range (..), RangeBorder (..), checkRange, mapRange, swapRange)
import Bio.Sequence.Utilities (unsafeEither)
getRange :: (IsSequence s, MonadError Text m, Complementary (Element s)) => s -> Range -> m [Element s]
getRange :: forall s (m :: * -> *).
(IsSequence s, MonadError Text m, Complementary (Element s)) =>
s -> Range -> m [Element s]
getRange s
s Range
r | Int -> Range -> Bool
checkRange (forall s. IsSequence s => s -> Int
length s
s) Range
r = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall s.
(IsSequence s, Complementary (Element s)) =>
s -> Range -> [Element s]
extractRange s
s Range
r
| Bool
otherwise = forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError Text
"Bio.Sequence.Functions.Sequence: invalid range in getRange."
extractRange :: (IsSequence s, Complementary (Element s)) => s -> Range -> [Element s]
s
s (Point Int
pos) = [s
s forall s. IsSequence s => s -> Int -> Element s
! Int
pos]
extractRange s
s (Span (RangeBorder Border
_ Int
lo) (RangeBorder Border
_ Int
hi)) = forall a. Int -> [a] -> [a]
L.drop Int
lo forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Int -> [a] -> [a]
L.take (Int
hi forall a. Num a => a -> a -> a
+ Int
1) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s. IsSequence s => s -> [Element s]
toList forall a b. (a -> b) -> a -> b
$ s
s
extractRange s
_ (Between Int
_ Int
_) = []
extractRange s
s (Join [Range]
ranges) = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (forall s.
(IsSequence s, Complementary (Element s)) =>
s -> Range -> [Element s]
extractRange s
s) [Range]
ranges
extractRange s
s (Complement Range
range) = forall a. Complementary a => a -> a
rcNA forall a b. (a -> b) -> a -> b
$ forall s.
(IsSequence s, Complementary (Element s)) =>
s -> Range -> [Element s]
extractRange s
s Range
range
unsafeGetRange :: (IsSequence s, Complementary (Element s)) => s -> Range -> [Element s]
unsafeGetRange :: forall s.
(IsSequence s, Complementary (Element s)) =>
s -> Range -> [Element s]
unsafeGetRange s
s = forall a. Either Text a -> a
unsafeEither forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *).
(IsSequence s, MonadError Text m, Complementary (Element s)) =>
s -> Range -> m [Element s]
getRange s
s
infixl 9 !
(!) :: IsSequence s => s -> Int -> Element s
! :: forall s. IsSequence s => s -> Int -> Element s
(!) s
s = forall a. a -> Maybe a -> a
fromMaybe (forall a. HasCallStack => [Char] -> a
error [Char]
"Bio.Sequence.Functions.Sequence: index out of Sequence's length.") forall b c a. (b -> c) -> (a -> b) -> a -> c
. (s
s forall s. IsSequence s => s -> Int -> Maybe (Element s)
!?)
infixl 9 !?
(!?) :: IsSequence s => s -> Int -> Maybe (Element s)
!? :: forall s. IsSequence s => s -> Int -> Maybe (Element s)
(!?) (forall s.
IsSequence s =>
s -> Sequence (Marking s) (Weight s) (Element s)
toSequence -> Sequence (Marking s) (Weight s) (Element s)
s) = ((Sequence (Marking s) (Weight s) (Element s)
s forall s a. s -> Getting a s a -> a
^. forall mk w a. Getter (Sequence mk w a) (Vector a)
sequ) forall a. Vector a -> Int -> Maybe a
V.!?)
toList :: IsSequence s => s -> [Element s]
toList :: forall s. IsSequence s => s -> [Element s]
toList = forall (t :: * -> *) a. Foldable t => t a -> [a]
F.toList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s.
IsSequence s =>
s -> Sequence (Marking s) (Weight s) (Element s)
toSequence
length :: IsSequence s => s -> Int
length :: forall s. IsSequence s => s -> Int
length = forall (t :: * -> *) a. Foldable t => t a -> Int
F.length forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s.
IsSequence s =>
s -> Sequence (Marking s) (Weight s) (Element s)
toSequence
null :: IsSequence s => s -> Bool
null :: forall s. IsSequence s => s -> Bool
null = forall (t :: * -> *) a. Foldable t => t a -> Bool
F.null forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s.
IsSequence s =>
s -> Sequence (Marking s) (Weight s) (Element s)
toSequence
reverse :: IsSequence s => s -> s
reverse :: forall s. IsSequence s => s -> s
reverse (forall s.
IsSequence s =>
s -> Sequence (Marking s) (Weight s) (Element s)
toSequence -> Sequence (Marking s) (Weight s) (Element s)
s) = s
res
where
newMaxInd :: Int
newMaxInd = forall s. IsSequence s => s -> Int
length Sequence (Marking s) (Weight s) (Element s)
s forall a. Num a => a -> a -> a
- Int
1
newSequ :: Vector (Element s)
newSequ = forall a. Vector a -> Vector a
V.reverse forall a b. (a -> b) -> a -> b
$ Sequence (Marking s) (Weight s) (Element s)
s forall s a. s -> Getting a s a -> a
^. forall mk w a. Getter (Sequence mk w a) (Vector a)
sequ
newMarkings :: [(Marking s, Range)]
newMarkings = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a -> b) -> a -> b
$ Range -> Range
swapRange forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Int) -> Range -> Range
mapRange ((-) Int
newMaxInd)) forall a b. (a -> b) -> a -> b
$ Sequence (Marking s) (Weight s) (Element s)
s forall s a. s -> Getting a s a -> a
^. forall mk w a. Getter (Sequence mk w a) [(mk, Range)]
markings
newWeights :: Vector (Weight s)
newWeights = forall a. Vector a -> Vector a
V.reverse forall a b. (a -> b) -> a -> b
$ Sequence (Marking s) (Weight s) (Element s)
s forall s a. s -> Getting a s a -> a
^. forall mk w a. Getter (Sequence mk w a) (Vector w)
weights
res :: s
res = forall s.
IsSequence s =>
Sequence (Marking s) (Weight s) (Element s) -> s
fromSequence forall a b. (a -> b) -> a -> b
$ forall a mk w.
Vector a -> [(mk, Range)] -> Vector w -> Sequence mk w a
_sequenceInner Vector (Element s)
newSequ [(Marking s, Range)]
newMarkings Vector (Weight s)
newWeights
drop :: ContainsNoMarking s => Int -> s -> s
drop :: forall s. ContainsNoMarking s => Int -> s -> s
drop Int
n (forall s.
IsSequence s =>
s -> Sequence (Marking s) (Weight s) (Element s)
toSequence -> Sequence (Marking s) (Weight s) (Element s)
s) | Int
n forall a. Ord a => a -> a -> Bool
< Int
0 = forall a. HasCallStack => [Char] -> a
error [Char]
"Bio.Sequence.Functions.Sequence: drop with negative value."
| Int
n forall a. Ord a => a -> a -> Bool
>= forall s. IsSequence s => s -> Int
length Sequence (Marking s) (Weight s) (Element s)
s = forall a. HasCallStack => [Char] -> a
error [Char]
"Bio.Sequence.Functions.Sequence: empty sequence as result of drop."
| Bool
otherwise = s
res
where
droppedSequ :: Vector (Element s)
droppedSequ = forall a. Int -> Vector a -> Vector a
V.drop Int
n forall a b. (a -> b) -> a -> b
$ Sequence (Marking s) (Weight s) (Element s)
s forall s a. s -> Getting a s a -> a
^. forall mk w a. Getter (Sequence mk w a) (Vector a)
sequ
newWeights :: Vector (Weight s)
newWeights = forall a. Int -> Vector a -> Vector a
V.drop Int
n forall a b. (a -> b) -> a -> b
$ Sequence (Marking s) (Weight s) (Element s)
s forall s a. s -> Getting a s a -> a
^. forall mk w a. Getter (Sequence mk w a) (Vector w)
weights
res :: s
res = forall s.
IsSequence s =>
Sequence (Marking s) (Weight s) (Element s) -> s
fromSequence forall a b. (a -> b) -> a -> b
$ forall a mk w.
Vector a -> [(mk, Range)] -> Vector w -> Sequence mk w a
_sequenceInner Vector (Element s)
droppedSequ forall a. Monoid a => a
mempty Vector (Weight s)
newWeights
take :: ContainsNoMarking s => Int -> s -> s
take :: forall s. ContainsNoMarking s => Int -> s -> s
take Int
n (forall s.
IsSequence s =>
s -> Sequence (Marking s) (Weight s) (Element s)
toSequence -> Sequence (Marking s) (Weight s) (Element s)
s) | Int
n forall a. Ord a => a -> a -> Bool
< Int
0 = forall a. HasCallStack => [Char] -> a
error [Char]
"Bio.Sequence.Functions.Sequence: take with negative value."
| Int
n forall a. Eq a => a -> a -> Bool
== Int
0 = forall a. HasCallStack => [Char] -> a
error [Char]
"Bio.Sequence.Functions.Sequence: empty sequence as result of take."
| Bool
otherwise = s
res
where
takenSequ :: Vector (Element s)
takenSequ = forall a. Int -> Vector a -> Vector a
V.take Int
n forall a b. (a -> b) -> a -> b
$ Sequence (Marking s) (Weight s) (Element s)
s forall s a. s -> Getting a s a -> a
^. forall mk w a. Getter (Sequence mk w a) (Vector a)
sequ
newWeights :: Vector (Weight s)
newWeights = forall a. Int -> Vector a -> Vector a
V.take Int
n forall a b. (a -> b) -> a -> b
$ Sequence (Marking s) (Weight s) (Element s)
s forall s a. s -> Getting a s a -> a
^. forall mk w a. Getter (Sequence mk w a) (Vector w)
weights
res :: s
res = forall s.
IsSequence s =>
Sequence (Marking s) (Weight s) (Element s) -> s
fromSequence forall a b. (a -> b) -> a -> b
$ forall a mk w.
Vector a -> [(mk, Range)] -> Vector w -> Sequence mk w a
_sequenceInner Vector (Element s)
takenSequ forall a. Monoid a => a
mempty Vector (Weight s)
newWeights
tail :: ContainsNoMarking s => s -> s
tail :: forall s. ContainsNoMarking s => s -> s
tail s
s | forall s. IsSequence s => s -> Int
length s
s forall a. Eq a => a -> a -> Bool
== Int
0 = forall a. HasCallStack => [Char] -> a
error [Char]
"Bio.Sequence.Functions.Sequence: tail from empty sequence."
| Bool
otherwise = forall s. ContainsNoMarking s => Int -> s -> s
drop Int
1 s
s