packages feed

fasta 0.6.1.1 → 0.6.2.0

raw patch · 9 files changed

+541/−2 lines, 9 filesdep +bytestringdep +pipes-bytestringPVP ok

version bump matches the API change (PVP)

Dependencies added: bytestring, pipes-bytestring

API changes (from Hackage documentation)

+ Data.Fasta.ByteString.Lazy.Parse: parseCLIPFasta :: ByteString -> CloneMap
+ Data.Fasta.ByteString.Lazy.Parse: parseFasta :: ByteString -> [FastaSequence]
+ Data.Fasta.ByteString.Lazy.Parse: pipesFasta :: MonadIO m => Producer ByteString m () -> Producer FastaSequence m ()
+ Data.Fasta.ByteString.Lazy.Parse: removeCLIPNs :: CloneMap -> CloneMap
+ Data.Fasta.ByteString.Lazy.Parse: removeN :: FastaSequence -> FastaSequence
+ Data.Fasta.ByteString.Lazy.Parse: removeNs :: [FastaSequence] -> [FastaSequence]
+ Data.Fasta.ByteString.Lazy.Translation: codon2aa :: Codon -> Either ByteString ByteString
+ Data.Fasta.ByteString.Lazy.Translation: translate :: Int64 -> FastaSequence -> Either ByteString FastaSequence
+ Data.Fasta.ByteString.Lazy.Types: FastaSequence :: ByteString -> ByteString -> FastaSequence
+ Data.Fasta.ByteString.Lazy.Types: class ShowFasta a
+ Data.Fasta.ByteString.Lazy.Types: data FastaSequence
+ Data.Fasta.ByteString.Lazy.Types: fastaHeader :: FastaSequence -> ByteString
+ Data.Fasta.ByteString.Lazy.Types: fastaSeq :: FastaSequence -> ByteString
+ Data.Fasta.ByteString.Lazy.Types: instance Eq FastaSequence
+ Data.Fasta.ByteString.Lazy.Types: instance Ord FastaSequence
+ Data.Fasta.ByteString.Lazy.Types: instance Show FastaSequence
+ Data.Fasta.ByteString.Lazy.Types: instance ShowFasta FastaSequence
+ Data.Fasta.ByteString.Lazy.Types: showFasta :: ShowFasta a => a -> ByteString
+ Data.Fasta.ByteString.Lazy.Types: type Clone = FastaSequence
+ Data.Fasta.ByteString.Lazy.Types: type CloneMap = Map (Int, Germline) [Clone]
+ Data.Fasta.ByteString.Lazy.Types: type Codon = ByteString
+ Data.Fasta.ByteString.Lazy.Types: type Germline = FastaSequence
+ Data.Fasta.ByteString.Parse: parseCLIPFasta :: ByteString -> CloneMap
+ Data.Fasta.ByteString.Parse: parseFasta :: ByteString -> [FastaSequence]
+ Data.Fasta.ByteString.Parse: pipesFasta :: MonadIO m => Producer ByteString m () -> Producer FastaSequence m ()
+ Data.Fasta.ByteString.Parse: removeCLIPNs :: CloneMap -> CloneMap
+ Data.Fasta.ByteString.Parse: removeN :: FastaSequence -> FastaSequence
+ Data.Fasta.ByteString.Parse: removeNs :: [FastaSequence] -> [FastaSequence]
+ Data.Fasta.ByteString.Translation: codon2aa :: Codon -> Either ByteString ByteString
+ Data.Fasta.ByteString.Translation: translate :: Int -> FastaSequence -> Either ByteString FastaSequence
+ Data.Fasta.ByteString.Types: FastaSequence :: ByteString -> ByteString -> FastaSequence
+ Data.Fasta.ByteString.Types: class ShowFasta a
+ Data.Fasta.ByteString.Types: data FastaSequence
+ Data.Fasta.ByteString.Types: fastaHeader :: FastaSequence -> ByteString
+ Data.Fasta.ByteString.Types: fastaSeq :: FastaSequence -> ByteString
+ Data.Fasta.ByteString.Types: instance Eq FastaSequence
+ Data.Fasta.ByteString.Types: instance Ord FastaSequence
+ Data.Fasta.ByteString.Types: instance Show FastaSequence
+ Data.Fasta.ByteString.Types: instance ShowFasta FastaSequence
+ Data.Fasta.ByteString.Types: showFasta :: ShowFasta a => a -> ByteString
+ Data.Fasta.ByteString.Types: type Clone = FastaSequence
+ Data.Fasta.ByteString.Types: type CloneMap = Map (Int, Germline) [Clone]
+ Data.Fasta.ByteString.Types: type Codon = ByteString
+ Data.Fasta.ByteString.Types: type Germline = FastaSequence

Files

fasta.cabal view
@@ -10,7 +10,7 @@ -- PVP summary:      +-+------- breaking API changes --                   | | +----- non-breaking API additions --                   | | | +--- code changes with no API change-version:             0.6.1.1+version:             0.6.2.0  -- A short (one-line) description of the package. synopsis:            A simple, mindless parser for fasta files.@@ -58,7 +58,15 @@                       Data.Fasta.Text.Lazy,                       Data.Fasta.Text.Lazy.Types,                       Data.Fasta.Text.Lazy.Parse,-                      Data.Fasta.Text.Lazy.Translation+                      Data.Fasta.Text.Lazy.Translation,+                      Data.Fasta.ByteString,+                      Data.Fasta.ByteString.Types,+                      Data.Fasta.ByteString.Parse,+                      Data.Fasta.ByteString.Translation,+                      Data.Fasta.ByteString.Lazy,+                      Data.Fasta.ByteString.Lazy.Types,+                      Data.Fasta.ByteString.Lazy.Parse,+                      Data.Fasta.ByteString.Lazy.Translation      -- Modules included in this library but not exported.   -- other-modules:       @@ -67,11 +75,13 @@   build-depends:       base >=4.6 && <4.9,                        parsec >=3.1 && <4.0,                        text >=1.1.0 && <1.4,+                       bytestring >=0.10 && <0.11,                        containers >= 0.5 && <0.6,                        split >= 0.2 && <0.3,                        pipes >= 4.1 && < 4.2,                        pipes-group >= 1.0 && < 1.1,                        pipes-text >= 0.0 && < 0.1,+                       pipes-bytestring >= 2.1 && < 2.2,                        lens >= 4.9 && < 4.10,                        foldl >= 1.0 && < 1.1   
+ src/Data/Fasta/ByteString.hs view
@@ -0,0 +1,14 @@+-- Data.Fasta.ByteString module.+-- By Gregory W. Schwartz+--+{- | Collects all application specific functions and types. Used here for Text.+-}++module Data.Fasta.ByteString ( module Data.Fasta.ByteString.Types+                             , module Data.Fasta.ByteString.Parse+                             , module Data.Fasta.ByteString.Translation ) where++-- Local+import Data.Fasta.ByteString.Types+import Data.Fasta.ByteString.Parse+import Data.Fasta.ByteString.Translation
+ src/Data/Fasta/ByteString/Lazy.hs view
@@ -0,0 +1,15 @@+-- Data.Fasta.Text.Lazy module.+-- By G.W. Schwartz+--+{- | Collects all application specific functions and types. Used here for+Text.Lazy+-}++module Data.Fasta.ByteString.Lazy ( module Data.Fasta.ByteString.Lazy.Types+                                  , module Data.Fasta.ByteString.Lazy.Parse+                                  , module Data.Fasta.ByteString.Lazy.Translation ) where++-- Local+import Data.Fasta.ByteString.Lazy.Types+import Data.Fasta.ByteString.Lazy.Parse+import Data.Fasta.ByteString.Lazy.Translation
+ src/Data/Fasta/ByteString/Lazy/Parse.hs view
@@ -0,0 +1,135 @@+-- Parse module.+-- By Gregory W. Schwartz+--+{- | Collection of functions for the parsing of a fasta file. Uses the lazy+- ByteString type.+-}++{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE BangPatterns #-}++module Data.Fasta.ByteString.Lazy.Parse ( parseFasta+                                        , parseCLIPFasta+                                        , pipesFasta+                                        , removeNs+                                        , removeN+                                        , removeCLIPNs ) where++-- Built-in+import Data.Char+import Control.Monad (void)+import Text.Parsec+import Text.Parsec.ByteString.Lazy+import qualified Data.Map.Strict as Map+import qualified Data.ByteString.Char8 as SB+import qualified Data.ByteString.Lazy.Char8 as B++-- Cabal+import Pipes+import qualified Pipes.Prelude as P+import qualified Pipes.ByteString as PB+import qualified Pipes.Group as PG+import Control.Lens (view)+import qualified Control.Foldl as FL++-- Local+import Data.Fasta.ByteString.Lazy.Types++eol :: Parsec B.ByteString u String+eol = choice . map (try . string) $ ["\n\r", "\r\n", "\n", "\r"]++eoe :: Parsec B.ByteString u ()+eoe  = do+    lookAhead (void $ char '>') <|> eof++fasta :: Parsec B.ByteString u FastaSequence+fasta = do+    spaces+    char '>'+    header <- manyTill (satisfy (/= '>')) eol+    fseq <- manyTill anyChar eoe+    return (FastaSequence { fastaHeader = B.pack header+                          , fastaSeq = B.pack+                                     . map toUpper+                                     . removeWhitespace $ fseq } )+  where+    removeWhitespace = filter (`notElem` ("\n\r " :: String))++fastaFile :: Parsec B.ByteString u [FastaSequence]+fastaFile = do+    spaces+    many fasta++fastaCLIP :: Parsec B.ByteString u (FastaSequence, [FastaSequence])+fastaCLIP = do+    spaces+    char '>'+    germline <- fasta+    clones <- many $ try fasta+    return (germline, clones)++fastaCLIPFile :: Parsec B.ByteString u [(FastaSequence, [FastaSequence])]+fastaCLIPFile = do+    spaces+    many fastaCLIP++-- | Parse a standard fasta file into lazy text sequences+parseFasta :: B.ByteString -> [FastaSequence]+parseFasta = eToV . parse fastaFile "error"+  where+    eToV (Right x) = x+    eToV (Left x)  = error ("Unable to parse fasta file\n" ++ show x)++-- | Parse a CLIP fasta file into lazy text sequences+parseCLIPFasta :: B.ByteString -> CloneMap+parseCLIPFasta = Map.fromList+               . map (\(!x, (!y, !z)) -> ((x, y), z))+               . zip [0..]+               . eToV+               . parse fastaCLIPFile "error"+  where+    eToV (Right x) = x+    eToV (Left x)  = error ("Unable to parse fasta file\n" ++ show x)++-- | Parse a standard fasta file into strict text sequences for pipes. This is+-- the highly recommeded way of parsing, as it is computationally fast and+-- uses memory based on line length+pipesFasta :: (MonadIO m)+           => Producer SB.ByteString m ()+           -> Producer FastaSequence m ()+pipesFasta p = FL.purely+               PG.folds+               FL.mconcat+               ( view (PB.splits (fromIntegral $ ord '>'))+               . PB.drop (1 :: Int)+               $ p )+           >-> P.map toFasta+  where+    toFasta x = FastaSequence { fastaHeader = B.fromChunks+                                            . take 1+                                            . SB.lines+                                            $ x+                              , fastaSeq    = B.fromChunks+                                            . tail+                                            . SB.lines+                                            $ x }++-- | Remove Ns from a collection of sequences+removeNs :: [FastaSequence] -> [FastaSequence]+removeNs = map (\x -> x { fastaSeq = noN . fastaSeq $ x })+  where+    noN = B.map (\y -> if (y /= 'N' && y /= 'n') then y else '-')++-- | Remove Ns from a sequence+removeN :: FastaSequence -> FastaSequence+removeN x = x { fastaSeq = noN . fastaSeq $ x }+  where+    noN = B.map (\y -> if (y /= 'N' && y /= 'n') then y else '-')++-- | Remove Ns from a collection of CLIP fasta sequences+removeCLIPNs :: CloneMap -> CloneMap+removeCLIPNs = Map.fromList . map remove . Map.toList+  where+    remove   ((!x, !y), !z)    = ((x, newSeq y), map newSeq z)+    newSeq !x = x { fastaSeq = noN . fastaSeq $ x }+    noN = B.map (\y -> if (y /= 'N' && y /= 'n') then y else '-')
+ src/Data/Fasta/ByteString/Lazy/Translation.hs view
@@ -0,0 +1,81 @@+-- Translation Module+-- By Gregory W. Schwartz++{- | Collects all functions pertaining to the translation of nucleotides to+amino acids for Lazy ByteString.+-}++{-# LANGUAGE OverloadedStrings #-}++module Data.Fasta.ByteString.Lazy.Translation ( codon2aa+                                              , translate ) where++-- Built in+import Data.Char+import Data.Either+import qualified Data.ByteString.Lazy.Char8 as BL+import Data.Int++-- Local+import Data.Fasta.ByteString.Lazy.Types++-- | Lazy ByteString version of chunksOf+chunksOf :: Int64 -> BL.ByteString -> [BL.ByteString]+chunksOf k = go+  where+    go t = case BL.splitAt k t of+             (a,b) | BL.null a    -> []+                   | otherwise    -> a : go b++-- | Converts a codon to an amino acid+-- Remember, if there is an "N" in that DNA sequence, then it is invalid+codon2aa :: Codon -> Either BL.ByteString BL.ByteString+codon2aa x+    | codon `elem` ["GCT", "GCC", "GCA", "GCG"]               = Right "A"+    | codon `elem` ["CGT", "CGC", "CGA", "CGG", "AGA", "AGG"] = Right "R"+    | codon `elem` ["AAT", "AAC"]                             = Right "N"+    | codon `elem` ["GAT", "GAC"]                             = Right "D"+    | codon `elem` ["TGT", "TGC"]                             = Right "C"+    | codon `elem` ["CAA", "CAG"]                             = Right "Q"+    | codon `elem` ["GAA", "GAG"]                             = Right "E"+    | codon `elem` ["GGT", "GGC", "GGA", "GGG"]               = Right "G"+    | codon `elem` ["CAT", "CAC"]                             = Right "H"+    | codon `elem` ["ATT", "ATC", "ATA"]                      = Right "I"+    | codon `elem` ["ATG"]                                    = Right "M"+    | codon `elem` ["TTA", "TTG", "CTT", "CTC", "CTA", "CTG"] = Right "L"+    | codon `elem` ["AAA", "AAG"]                             = Right "K"+    | codon `elem` ["TTT", "TTC"]                             = Right "F"+    | codon `elem` ["CCT", "CCC", "CCA", "CCG"]               = Right "P"+    | codon `elem` ["TCT", "TCC", "TCA", "TCG", "AGT", "AGC"] = Right "S"+    | codon `elem` ["ACT", "ACC", "ACA", "ACG"]               = Right "T"+    | codon `elem` ["TGG"]                                    = Right "W"+    | codon `elem` ["TAT", "TAC"]                             = Right "Y"+    | codon `elem` ["GTT", "GTC", "GTA", "GTG"]               = Right "V"+    | codon `elem` ["TAA", "TGA", "TAG"]                      = Right "*"+    | codon `elem` ["---", "..."]                             = Right "-"+    | codon == "~~~"                                          = Right "-"+    | 'N' `BL.elem` codon                                     = Right "-"+    | '-' `BL.elem` codon                                     = Right "-"+    | '.' `BL.elem` codon                                     = Right "-"+    | otherwise                                               = Left errorMsg+  where+    codon    = BL.map toUpper x+    errorMsg = BL.append "Unidentified codon: " codon++-- | Translates a string of nucleotides. Returns a text with the error if the+-- codon is invalid.+translate :: Int64 -> FastaSequence -> Either BL.ByteString FastaSequence+translate pos x+    | any isLeft' translation = Left $ head . lefts $ translation+    | otherwise               = Right $ x { fastaSeq = BL.concat+                                                     . rights+                                                     $ translation }+  where+    translation = map codon2aa+                . filter ((== 3) . BL.length)+                . chunksOf 3+                . BL.drop (pos - 1)+                . fastaSeq+                $ x+    isLeft' (Left _) = True+    isLeft' _        = False
+ src/Data/Fasta/ByteString/Lazy/Types.hs view
@@ -0,0 +1,39 @@+-- Types module.+-- By G.W. Schwartz+--+{- | Collects all application specific types. Used here for ByteString.Lazy+-}++{-# LANGUAGE OverloadedStrings #-}++module Data.Fasta.ByteString.Lazy.Types where++-- Built-in+import qualified Data.ByteString.Lazy.Char8 as BL+import qualified Data.Map as M++-- Algebraic+data FastaSequence = FastaSequence { fastaHeader :: BL.ByteString+                                   , fastaSeq    :: BL.ByteString+                                   } deriving (Eq, Ord, Show)++-- Basic+type Clone    = FastaSequence+type Germline = FastaSequence+type Codon    = BL.ByteString++-- Advanced+-- | A clone is a collection of sequences derived from a germline with+-- a specific identifier+type CloneMap = M.Map (Int, Germline) [Clone]++-- Classes+class ShowFasta a where+    showFasta :: a -> BL.ByteString++-- Instances+instance ShowFasta FastaSequence where+    showFasta FastaSequence {fastaHeader = x, fastaSeq = y} = BL.concat [ ">"+                                                                        , x+                                                                        , "\n"+                                                                        , y ]
+ src/Data/Fasta/ByteString/Parse.hs view
@@ -0,0 +1,126 @@+-- Parse module.+-- By Gregory W. Schwartz+--+{- | Collection of functions for the parsing of a fasta file. Uses the+- ByteString type.+-}++{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE BangPatterns #-}++module Data.Fasta.ByteString.Parse ( parseFasta+                                   , parseCLIPFasta+                                   , pipesFasta+                                   , removeNs+                                   , removeN+                                   , removeCLIPNs ) where++-- Built-in+import Data.Char+import Text.Parsec+import Text.Parsec.ByteString+import qualified Data.Map.Strict as Map+import qualified Data.ByteString.Char8 as B++-- Cabal+import Pipes+import qualified Pipes.Prelude as P+import qualified Pipes.ByteString as PB+import qualified Pipes.Group as PG+import Control.Lens (view)+import qualified Control.Foldl as FL++-- Local+import Data.Fasta.ByteString.Types++eol :: Parsec B.ByteString u String+eol = choice . map (try . string) $ ["\n\r", "\r\n", "\n", "\r"]++eoe :: Parsec B.ByteString u ()+eoe = lookAhead (void $ char '>') <|> eof++fasta :: Parsec B.ByteString u FastaSequence+fasta = do+    spaces+    char '>'+    header <- manyTill (satisfy (/= '>')) eol+    fseq <- manyTill anyChar eoe+    return (FastaSequence { fastaHeader = B.pack header+                          , fastaSeq = B.pack+                                     . map toUpper+                                     . removeWhitespace+                                     $ fseq } )+  where+    removeWhitespace = filter (`notElem` ("\n\r " :: String))++fastaFile :: Parsec B.ByteString u [FastaSequence]+fastaFile = do+    spaces+    many fasta++fastaCLIP :: Parsec B.ByteString u (FastaSequence, [FastaSequence])+fastaCLIP = do+    spaces+    char '>'+    germline <- fasta+    clones <- many $ try fasta+    return (germline, clones)++fastaCLIPFile :: Parsec B.ByteString u [(FastaSequence, [FastaSequence])]+fastaCLIPFile = do+    spaces+    many fastaCLIP++-- | Parse a standard fasta file into text sequences+parseFasta :: B.ByteString -> [FastaSequence]+parseFasta = eToV . parse fastaFile "error"+  where+    eToV (Right x) = x+    eToV (Left x)  = error ("Unable to parse fasta file\n" ++ show x)++-- | Parse a CLIP fasta file into text sequences+parseCLIPFasta :: B.ByteString -> CloneMap+parseCLIPFasta = Map.fromList+               . map (\(!x, (!y, !z)) -> ((x, y), z))+               . zip [0..]+               . eToV+               . parse fastaCLIPFile "error"+  where+    eToV (Right x) = x+    eToV (Left x)  = error ("Unable to parse fasta file\n" ++ show x)++-- | Parse a standard fasta file into strict text sequences for pipes. This is+-- the highly recommeded way of parsing, as it is computationally fast and+-- uses memory based on line length+pipesFasta :: (MonadIO m) => Producer B.ByteString m ()+                          -> Producer FastaSequence m ()+pipesFasta p = FL.purely+               PG.folds+               FL.mconcat+               ( view (PB.splits (fromIntegral $ ord '>'))+               . PB.drop (1 :: Int)+               $ p )+           >-> P.map toFasta+  where+    toFasta x = FastaSequence { fastaHeader = head . B.lines $ x+                              , fastaSeq    = B.concat . tail . B.lines $ x }++-- | Remove Ns from a collection of sequences+removeNs :: [FastaSequence] -> [FastaSequence]+removeNs = map (\x -> x { fastaSeq = noN . fastaSeq $ x })+  where+    noN = B.map (\y -> if y /= 'N' && y /= 'n' then y else '-')++-- | Remove Ns from a sequence+removeN :: FastaSequence -> FastaSequence+removeN x = x { fastaSeq = noN . fastaSeq $ x }+  where+    noN = B.map (\y -> if y /= 'N' && y /= 'n' then y else '-')++-- | Remove Ns from a collection of CLIP fasta sequences+removeCLIPNs :: CloneMap -> CloneMap+removeCLIPNs = Map.fromList . map remove . Map.toList+  where+    remove   ((!x, !y), !z)    = ((x, newSeq y), map newSeq z)+    newSeq !x = x { fastaSeq = noN . fastaSeq $ x }+    noN = B.map (\y -> if y /= 'N' && y /= 'n' then y else '-')
+ src/Data/Fasta/ByteString/Translation.hs view
@@ -0,0 +1,80 @@+-- Translation Module+-- By Gregory W. Schwartz++{- | Collects all functions pertaining to the translation of nucleotides to+amino acids for ByteStrings+-}++{-# LANGUAGE OverloadedStrings #-}++module Data.Fasta.ByteString.Translation ( codon2aa+                                         , translate ) where++-- Built in+import Data.Char+import Data.Either+import qualified Data.ByteString.Char8 as B++-- Local+import Data.Fasta.ByteString.Types++-- | ByteString version of chunksOf+chunksOf :: Int -> B.ByteString -> [B.ByteString]+chunksOf k = go+  where+    go t = case B.splitAt k t of+             (a,b) | B.null a    -> []+                   | otherwise    -> a : go b++-- | Converts a codon to an amino acid+-- Remember, if there is an "N" in that DNA sequence, then it is invalid+codon2aa :: Codon -> Either B.ByteString B.ByteString+codon2aa x+    | codon `elem` ["GCT", "GCC", "GCA", "GCG"]               = Right "A"+    | codon `elem` ["CGT", "CGC", "CGA", "CGG", "AGA", "AGG"] = Right "R"+    | codon `elem` ["AAT", "AAC"]                             = Right "N"+    | codon `elem` ["GAT", "GAC"]                             = Right "D"+    | codon `elem` ["TGT", "TGC"]                             = Right "C"+    | codon `elem` ["CAA", "CAG"]                             = Right "Q"+    | codon `elem` ["GAA", "GAG"]                             = Right "E"+    | codon `elem` ["GGT", "GGC", "GGA", "GGG"]               = Right "G"+    | codon `elem` ["CAT", "CAC"]                             = Right "H"+    | codon `elem` ["ATT", "ATC", "ATA"]                      = Right "I"+    | codon `elem` ["ATG"]                                    = Right "M"+    | codon `elem` ["TTA", "TTG", "CTT", "CTC", "CTA", "CTG"] = Right "L"+    | codon `elem` ["AAA", "AAG"]                             = Right "K"+    | codon `elem` ["TTT", "TTC"]                             = Right "F"+    | codon `elem` ["CCT", "CCC", "CCA", "CCG"]               = Right "P"+    | codon `elem` ["TCT", "TCC", "TCA", "TCG", "AGT", "AGC"] = Right "S"+    | codon `elem` ["ACT", "ACC", "ACA", "ACG"]               = Right "T"+    | codon `elem` ["TGG"]                                    = Right "W"+    | codon `elem` ["TAT", "TAC"]                             = Right "Y"+    | codon `elem` ["GTT", "GTC", "GTA", "GTG"]               = Right "V"+    | codon `elem` ["TAA", "TGA", "TAG"]                      = Right "*"+    | codon `elem` ["---", "..."]                             = Right "-"+    | codon == "~~~"                                          = Right "-"+    | "N" `B.isInfixOf` codon                                 = Right "-"+    | "-" `B.isInfixOf` codon                                 = Right "-"+    | "." `B.isInfixOf` codon                                 = Right "-"+    | otherwise                                               = Left errorMsg+  where+    codon    = B.map toUpper x+    errorMsg = B.append "Unidentified codon: " codon++-- | Translates a string of nucleotides. Returns a text with the error if the+-- codon is invalid.+translate :: Int -> FastaSequence -> Either B.ByteString FastaSequence+translate pos x+    | any isLeft' translation = Left $ head . lefts $ translation+    | otherwise               = Right $ x { fastaSeq = B.concat+                                                     . rights+                                                     $ translation }+  where+    translation = map codon2aa+                . filter ((== 3) . B.length)+                . chunksOf 3+                . B.drop (pos - 1)+                . fastaSeq+                $ x+    isLeft' (Left _) = True+    isLeft' _        = False
+ src/Data/Fasta/ByteString/Types.hs view
@@ -0,0 +1,39 @@+-- Types module.+-- By Gregory W. Schwartz+--+{- | Collects all application specific types. Used here for Text.+-}++{-# LANGUAGE OverloadedStrings #-}++module Data.Fasta.ByteString.Types where++-- Built-in+import qualified Data.ByteString.Char8 as B+import qualified Data.Map as M++-- Algebraic+data FastaSequence = FastaSequence { fastaHeader :: B.ByteString+                                   , fastaSeq    :: B.ByteString+                                   } deriving (Eq, Ord, Show)++-- Basic+type Clone    = FastaSequence+type Germline = FastaSequence+type Codon    = B.ByteString++-- Advanced+-- | A clone is a collection of sequences derived from a germline with+-- a specific identifier+type CloneMap = M.Map (Int, Germline) [Clone]++-- Classes+class ShowFasta a where+    showFasta :: a -> B.ByteString++-- Instances+instance ShowFasta FastaSequence where+    showFasta FastaSequence {fastaHeader = x, fastaSeq = y} = B.concat [ ">"+                                                                       , x+                                                                       , "\n"+                                                                       , y ]