{-# OPTIONS_GHC -fno-warn-orphans  #-}

module Bio.NucleicAcid.Nucleotide.Instances () where

import           Bio.NucleicAcid.Nucleotide.Type
import           Bio.Utils.Monomer               (FromSymbol (..), Symbol (..))
import           Data.Array                      (Array, listArray)
import           Data.String                     (IsString (..))

-------------------------------------------------------------------------------
-- Symbol and ThreeSymbols
-------------------------------------------------------------------------------

instance Symbol DNA where
    symbol :: DNA -> Char
symbol DNA
DA = Char
'A'
    symbol DNA
DC = Char
'C'
    symbol DNA
DG = Char
'G'
    symbol DNA
DT = Char
'T'

instance FromSymbol DNA where
    fromSymbolE :: Char -> Either Char DNA
fromSymbolE Char
'A' = DNA -> Either Char DNA
forall a b. b -> Either a b
Right DNA
DA
    fromSymbolE Char
'C' = DNA -> Either Char DNA
forall a b. b -> Either a b
Right DNA
DC
    fromSymbolE Char
'G' = DNA -> Either Char DNA
forall a b. b -> Either a b
Right DNA
DG
    fromSymbolE Char
'T' = DNA -> Either Char DNA
forall a b. b -> Either a b
Right DNA
DT
    fromSymbolE Char
ch  = Char -> Either Char DNA
forall a b. a -> Either a b
Left Char
ch

instance Symbol RNA where
    symbol :: RNA -> Char
symbol RNA
RA = Char
'A'
    symbol RNA
RC = Char
'C'
    symbol RNA
RG = Char
'G'
    symbol RNA
RU = Char
'U'

instance FromSymbol RNA where
    fromSymbolE :: Char -> Either Char RNA
fromSymbolE Char
'A' = RNA -> Either Char RNA
forall a b. b -> Either a b
Right RNA
RA
    fromSymbolE Char
'C' = RNA -> Either Char RNA
forall a b. b -> Either a b
Right RNA
RC
    fromSymbolE Char
'G' = RNA -> Either Char RNA
forall a b. b -> Either a b
Right RNA
RG
    fromSymbolE Char
'U' = RNA -> Either Char RNA
forall a b. b -> Either a b
Right RNA
RU
    fromSymbolE Char
ch  = Char -> Either Char RNA
forall a b. a -> Either a b
Left Char
ch

-------------------------------------------------------------------------------
-- IsString
-------------------------------------------------------------------------------

instance {-# OVERLAPPING #-} IsString [DNA] where
    fromString :: String -> [DNA]
fromString String
s =
        case (Char -> Either Char DNA) -> String -> Either Char [DNA]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse Char -> Either Char DNA
forall a. FromSymbol a => Char -> Either Char a
fromSymbolE String
s of
            Right [DNA]
l -> [DNA]
l
            Left Char
e  -> String -> [DNA]
forall a. HasCallStack => String -> a
error (String -> [DNA]) -> String -> [DNA]
forall a b. (a -> b) -> a -> b
$ String
"Bio.NucleicAcid.Nucleotide.Instances: could not read nucleotide " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> [Char
e]

instance IsString (Array Int DNA) where
    fromString :: String -> Array Int DNA
fromString String
s = (Int, Int) -> [DNA] -> Array Int DNA
forall i e. Ix i => (i, i) -> [e] -> Array i e
listArray (Int
0, String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
s Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) ([DNA] -> Array Int DNA) -> [DNA] -> Array Int DNA
forall a b. (a -> b) -> a -> b
$ String -> [DNA]
forall a. IsString a => String -> a
fromString String
s

instance {-# OVERLAPPING #-} IsString [RNA] where
    fromString :: String -> [RNA]
fromString String
s =
        case (Char -> Either Char RNA) -> String -> Either Char [RNA]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse Char -> Either Char RNA
forall a. FromSymbol a => Char -> Either Char a
fromSymbolE String
s of
            Right [RNA]
l -> [RNA]
l
            Left Char
e  -> String -> [RNA]
forall a. HasCallStack => String -> a
error (String -> [RNA]) -> String -> [RNA]
forall a b. (a -> b) -> a -> b
$ String
"Bio.NucleicAcid.Nucleotide.Instances: could not read nucleotide " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> [Char
e]

instance IsString (Array Int RNA) where
    fromString :: String -> Array Int RNA
fromString String
s = (Int, Int) -> [RNA] -> Array Int RNA
forall i e. Ix i => (i, i) -> [e] -> Array i e
listArray (Int
0, String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
s Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) ([RNA] -> Array Int RNA) -> [RNA] -> Array Int RNA
forall a b. (a -> b) -> a -> b
$ String -> [RNA]
forall a. IsString a => String -> a
fromString String
s