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

-- |
-- Module      :  ELynx.Data.AminoAcid
-- Description :  Amino acid related types and functions
-- Copyright   :  (c) Dominik Schrempf 2021
-- 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.Data.Alphabet.Alphabet'.
--
-- Amino acids in alphabetical order.
--
-- @
-- 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
-- @
module ELynx.Data.Character.AminoAcid
  ( AminoAcid (..),
  )
where

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

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

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

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

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

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