{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}

-- |
-- Module      :  ELynx.AminoAcid
-- Description :  Amino acid related types and functions
-- Copyright   :  2021 Dominik Schrempf
-- License     :  GPL-3.0-or-later
--
-- Maintainer  :  dominik.schrempf@gmail.com
-- Stability   :  unstable
-- Portability :  portable
--
-- Creation date: Thu Oct  4 18:26:35 2018.
--
-- See header of 'ELynx.Alphabet.Alphabet'.
--
-- Extended amino acid with gaps. See also
-- https://www.bioinformatics.org/sms/iupac.html or
-- https://en.wikipedia.org/wiki/International_Union_of_Pure_and_Applied_Chemistry.
--
-- @
-- Amino Acid Code:  Three letter Code:  Amino Acid:
-- ----------------  ------------------  -----------
-- A                 Ala                 Alanine
-- C                 Cys                 Cysteine
-- D                 Asp                 Aspartic Acid
-- E                 Glu                 Glutamic Acid
-- F                 Phe                 Phenylalanine
-- G                 Gly                 Glycine
-- H                 His                 Histidine
-- I                 Ile                 Isoleucine
-- K                 Lys                 Lysine
-- L                 Leu                 Leucine
-- M                 Met                 Methionine
-- N                 Asn                 Asparagine
-- P                 Pro                 Proline
-- Q                 Gln                 Glutamine
-- R                 Arg                 Arginine
-- S                 Ser                 Serine
-- T                 Thr                 Threonine
-- V                 Val                 Valine
-- W                 Trp                 Tryptophan
-- Y                 Tyr                 Tyrosine
-- ----------------  ------------------  -----------
-- -                 Gap                 No amino acid
-- .                 Gap                 No amino acid
-- @
module ELynx.Character.AminoAcidX
  ( AminoAcidX (..),
  )
where

import Data.ByteString.Internal (c2w, w2c)
import Data.Vector.Unboxed.Deriving
import Data.Word8
import qualified ELynx.Character.Character as C

-- | Amino acids.
data AminoAcidX
  = A
  | C
  | D
  | E
  | F
  | G
  | H
  | I
  | K
  | L
  | M
  | N
  | P
  | Q
  | R
  | S
  | T
  | V
  | W
  | Y
  | Gap
  deriving (Int -> AminoAcidX -> ShowS
[AminoAcidX] -> ShowS
AminoAcidX -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AminoAcidX] -> ShowS
$cshowList :: [AminoAcidX] -> ShowS
show :: AminoAcidX -> String
$cshow :: AminoAcidX -> String
showsPrec :: Int -> AminoAcidX -> ShowS
$cshowsPrec :: Int -> AminoAcidX -> ShowS
Show, ReadPrec [AminoAcidX]
ReadPrec AminoAcidX
Int -> ReadS AminoAcidX
ReadS [AminoAcidX]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [AminoAcidX]
$creadListPrec :: ReadPrec [AminoAcidX]
readPrec :: ReadPrec AminoAcidX
$creadPrec :: ReadPrec AminoAcidX
readList :: ReadS [AminoAcidX]
$creadList :: ReadS [AminoAcidX]
readsPrec :: Int -> ReadS AminoAcidX
$creadsPrec :: Int -> ReadS AminoAcidX
Read, AminoAcidX -> AminoAcidX -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AminoAcidX -> AminoAcidX -> Bool
$c/= :: AminoAcidX -> AminoAcidX -> Bool
== :: AminoAcidX -> AminoAcidX -> Bool
$c== :: AminoAcidX -> AminoAcidX -> Bool
Eq, Eq AminoAcidX
AminoAcidX -> AminoAcidX -> Bool
AminoAcidX -> AminoAcidX -> Ordering
AminoAcidX -> AminoAcidX -> AminoAcidX
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 :: AminoAcidX -> AminoAcidX -> AminoAcidX
$cmin :: AminoAcidX -> AminoAcidX -> AminoAcidX
max :: AminoAcidX -> AminoAcidX -> AminoAcidX
$cmax :: AminoAcidX -> AminoAcidX -> AminoAcidX
>= :: AminoAcidX -> AminoAcidX -> Bool
$c>= :: AminoAcidX -> AminoAcidX -> Bool
> :: AminoAcidX -> AminoAcidX -> Bool
$c> :: AminoAcidX -> AminoAcidX -> Bool
<= :: AminoAcidX -> AminoAcidX -> Bool
$c<= :: AminoAcidX -> AminoAcidX -> Bool
< :: AminoAcidX -> AminoAcidX -> Bool
$c< :: AminoAcidX -> AminoAcidX -> Bool
compare :: AminoAcidX -> AminoAcidX -> Ordering
$ccompare :: AminoAcidX -> AminoAcidX -> Ordering
Ord, Int -> AminoAcidX
AminoAcidX -> Int
AminoAcidX -> [AminoAcidX]
AminoAcidX -> AminoAcidX
AminoAcidX -> AminoAcidX -> [AminoAcidX]
AminoAcidX -> AminoAcidX -> AminoAcidX -> [AminoAcidX]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: AminoAcidX -> AminoAcidX -> AminoAcidX -> [AminoAcidX]
$cenumFromThenTo :: AminoAcidX -> AminoAcidX -> AminoAcidX -> [AminoAcidX]
enumFromTo :: AminoAcidX -> AminoAcidX -> [AminoAcidX]
$cenumFromTo :: AminoAcidX -> AminoAcidX -> [AminoAcidX]
enumFromThen :: AminoAcidX -> AminoAcidX -> [AminoAcidX]
$cenumFromThen :: AminoAcidX -> AminoAcidX -> [AminoAcidX]
enumFrom :: AminoAcidX -> [AminoAcidX]
$cenumFrom :: AminoAcidX -> [AminoAcidX]
fromEnum :: AminoAcidX -> Int
$cfromEnum :: AminoAcidX -> Int
toEnum :: Int -> AminoAcidX
$ctoEnum :: Int -> AminoAcidX
pred :: AminoAcidX -> AminoAcidX
$cpred :: AminoAcidX -> AminoAcidX
succ :: AminoAcidX -> AminoAcidX
$csucc :: AminoAcidX -> AminoAcidX
Enum, AminoAcidX
forall a. a -> a -> Bounded a
maxBound :: AminoAcidX
$cmaxBound :: AminoAcidX
minBound :: AminoAcidX
$cminBound :: AminoAcidX
Bounded)

toWord :: AminoAcidX -> Word8
toWord :: AminoAcidX -> Word8
toWord AminoAcidX
A = Char -> Word8
c2w Char
'A'
toWord AminoAcidX
C = Char -> Word8
c2w Char
'C'
toWord AminoAcidX
D = Char -> Word8
c2w Char
'D'
toWord AminoAcidX
E = Char -> Word8
c2w Char
'E'
toWord AminoAcidX
F = Char -> Word8
c2w Char
'F'
toWord AminoAcidX
G = Char -> Word8
c2w Char
'G'
toWord AminoAcidX
H = Char -> Word8
c2w Char
'H'
toWord AminoAcidX
I = Char -> Word8
c2w Char
'I'
toWord AminoAcidX
K = Char -> Word8
c2w Char
'K'
toWord AminoAcidX
L = Char -> Word8
c2w Char
'L'
toWord AminoAcidX
M = Char -> Word8
c2w Char
'M'
toWord AminoAcidX
N = Char -> Word8
c2w Char
'N'
toWord AminoAcidX
P = Char -> Word8
c2w Char
'P'
toWord AminoAcidX
Q = Char -> Word8
c2w Char
'Q'
toWord AminoAcidX
R = Char -> Word8
c2w Char
'R'
toWord AminoAcidX
S = Char -> Word8
c2w Char
'S'
toWord AminoAcidX
T = Char -> Word8
c2w Char
'T'
toWord AminoAcidX
V = Char -> Word8
c2w Char
'V'
toWord AminoAcidX
W = Char -> Word8
c2w Char
'W'
toWord AminoAcidX
Y = Char -> Word8
c2w Char
'Y'
toWord AminoAcidX
Gap = Char -> Word8
c2w Char
'-'

fromWord :: Word8 -> AminoAcidX
fromWord :: Word8 -> AminoAcidX
fromWord Word8
w = case Word8 -> Char
w2c Word8
w of
  Char
'A' -> AminoAcidX
A
  Char
'C' -> AminoAcidX
C
  Char
'D' -> AminoAcidX
D
  Char
'E' -> AminoAcidX
E
  Char
'F' -> AminoAcidX
F
  Char
'G' -> AminoAcidX
G
  Char
'H' -> AminoAcidX
H
  Char
'I' -> AminoAcidX
I
  Char
'K' -> AminoAcidX
K
  Char
'L' -> AminoAcidX
L
  Char
'M' -> AminoAcidX
M
  Char
'N' -> AminoAcidX
N
  Char
'P' -> AminoAcidX
P
  Char
'Q' -> AminoAcidX
Q
  Char
'R' -> AminoAcidX
R
  Char
'S' -> AminoAcidX
S
  Char
'T' -> AminoAcidX
T
  Char
'V' -> AminoAcidX
V
  Char
'W' -> AminoAcidX
W
  Char
'Y' -> AminoAcidX
Y
  Char
'-' -> AminoAcidX
Gap
  Char
'.' -> AminoAcidX
Gap
  Char
_ -> forall a. HasCallStack => String -> a
error String
"fromWord: Cannot convert to AminoAcidX."

derivingUnbox
  "AminoAcidX"
  [t|AminoAcidX -> Word8|]
  [|toWord|]
  [|fromWord|]

instance C.Character AminoAcidX where
  toWord :: AminoAcidX -> Word8
toWord = AminoAcidX -> Word8
toWord
  fromWord :: Word8 -> AminoAcidX
fromWord = Word8 -> AminoAcidX
fromWord

instance C.CharacterX AminoAcidX where
  gap :: AminoAcidX
gap = AminoAcidX
Gap