{-# 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' = forall a b. b -> Either a b
Right DNA
DA
    fromSymbolE Char
'C' = forall a b. b -> Either a b
Right DNA
DC
    fromSymbolE Char
'G' = forall a b. b -> Either a b
Right DNA
DG
    fromSymbolE Char
'T' = forall a b. b -> Either a b
Right DNA
DT
    fromSymbolE Char
ch  = 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' = forall a b. b -> Either a b
Right RNA
RA
    fromSymbolE Char
'C' = forall a b. b -> Either a b
Right RNA
RC
    fromSymbolE Char
'G' = forall a b. b -> Either a b
Right RNA
RG
    fromSymbolE Char
'U' = forall a b. b -> Either a b
Right RNA
RU
    fromSymbolE Char
ch  = forall a b. a -> Either a b
Left Char
ch

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

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

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

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

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