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

module Bio.Protein.AminoAcid.Instances where

import           Bio.Protein.AminoAcid.Type
import           Bio.Utils.Monomer          (FromSymbol (..),
                                             FromThreeSymbols (..), Symbol (..),
                                             ThreeSymbols (..))
import           Control.Lens               (Const (..), Getting, Identity (..),
                                             Lens', coerced, to, (^.))
import           Data.Array                 (Array, listArray)
import           Data.Coerce                (coerce)
import           Data.Kind                  (Type)
import           Data.String                (IsString (..))

-------------------------------------------------------------------------------
-- Creatable
-------------------------------------------------------------------------------

-- | Single object can be created
--
class Createable a where
    type Create a :: Type
    -- | Function to create single object
    --
    create :: Create a

instance Createable (BB a) where
    type Create (BB a) = a -> a -> a -> BB a
    create :: Create (BB a)
create a
n_ a
ca_ a
c_ = coerce :: forall a b. Coercible a b => a -> b
coerce forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (nr :: * -> *) (car :: * -> *) (cr :: * -> *) a.
nr a -> car a -> cr a -> AminoAcid nr car cr a
AminoAcid (forall (f :: * -> *) a. Applicative f => a -> f a
pure a
n_) (forall (f :: * -> *) a. Applicative f => a -> f a
pure a
ca_) (forall (f :: * -> *) a. Applicative f => a -> f a
pure a
c_)

instance Createable (BBCA a) where
    type Create (BBCA a) = a -> BBCA a
    create :: Create (BBCA a)
create a
ca_ = coerce :: forall a b. Coercible a b => a -> b
coerce forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (nr :: * -> *) (car :: * -> *) (cr :: * -> *) a.
nr a -> car a -> cr a -> AminoAcid nr car cr a
AminoAcid (forall {k} a (b :: k). a -> Const a b
Const ()) (forall (f :: * -> *) a. Applicative f => a -> f a
pure a
ca_) (forall {k} a (b :: k). a -> Const a b
Const ())

instance Createable (BBT a) where
    type Create (BBT a) = a -> a -> a -> AA -> BBT a
    create :: Create (BBT a)
create a
n_ a
ca_ a
c_ AA
aa = coerce :: forall a b. Coercible a b => a -> b
coerce forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (nr :: * -> *) (car :: * -> *) (cr :: * -> *) a.
nr a -> car a -> cr a -> AminoAcid nr car cr a
AminoAcid (forall (f :: * -> *) a. Applicative f => a -> f a
pure a
n_) (forall (r :: * -> *) a. a -> r a -> Env r a
Env a
ca_ (forall {k} a (b :: k). a -> Const a b
Const AA
aa)) (forall (f :: * -> *) a. Applicative f => a -> f a
pure a
c_)

instance Createable (BBCAT a) where
    type Create (BBCAT a) = a -> AA -> BBCAT a
    create :: Create (BBCAT a)
create a
ca_ AA
aa = coerce :: forall a b. Coercible a b => a -> b
coerce forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (nr :: * -> *) (car :: * -> *) (cr :: * -> *) a.
nr a -> car a -> cr a -> AminoAcid nr car cr a
AminoAcid (forall {k} a (b :: k). a -> Const a b
Const ()) (forall (r :: * -> *) a. a -> r a -> Env r a
Env a
ca_ (forall {k} a (b :: k). a -> Const a b
Const AA
aa)) (forall {k} a (b :: k). a -> Const a b
Const ())

instance Createable (BBCG a) where
    type Create (BBCG a) = a -> a -> a -> a -> AA -> BBCG a
    create :: Create (BBCG a)
create a
n_ a
ca_ a
c_ a
cg_ AA
aa = coerce :: forall a b. Coercible a b => a -> b
coerce forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (nr :: * -> *) (car :: * -> *) (cr :: * -> *) a.
nr a -> car a -> cr a -> AminoAcid nr car cr a
AminoAcid (forall (f :: * -> *) a. Applicative f => a -> f a
pure a
n_) (forall (r :: * -> *) a. a -> r a -> Env r a
Env a
ca_ (forall a. a -> AA -> CG a
CG a
cg_ AA
aa)) (forall (f :: * -> *) a. Applicative f => a -> f a
pure a
c_)

instance Createable (BBO a) where
    type Create (BBO a) = a -> a -> a -> a -> BBO a
    create :: Create (BBO a)
create a
n_ a
ca_ a
c_ a
o_ = coerce :: forall a b. Coercible a b => a -> b
coerce forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (nr :: * -> *) (car :: * -> *) (cr :: * -> *) a.
nr a -> car a -> cr a -> AminoAcid nr car cr a
AminoAcid (forall (f :: * -> *) a. Applicative f => a -> f a
pure a
n_) (forall (f :: * -> *) a. Applicative f => a -> f a
pure a
ca_) (forall (r :: * -> *) a. a -> r a -> Env r a
Env a
c_ (forall (f :: * -> *) a. Applicative f => a -> f a
pure a
o_))

instance Createable (BBOT a) where
    type Create (BBOT a) = a -> a -> a -> a -> AA -> BBOT a
    create :: Create (BBOT a)
create a
n_ a
ca_ a
c_ a
o_ AA
aa = coerce :: forall a b. Coercible a b => a -> b
coerce forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (nr :: * -> *) (car :: * -> *) (cr :: * -> *) a.
nr a -> car a -> cr a -> AminoAcid nr car cr a
AminoAcid (forall (f :: * -> *) a. Applicative f => a -> f a
pure a
n_) (forall (r :: * -> *) a. a -> r a -> Env r a
Env a
ca_ (forall {k} a (b :: k). a -> Const a b
Const AA
aa)) (forall (r :: * -> *) a. a -> r a -> Env r a
Env a
c_ (forall (f :: * -> *) a. Applicative f => a -> f a
pure a
o_))

instance Createable (BBOCG a) where
    type Create (BBOCG a) = a -> a -> a -> a -> a -> AA -> BBOCG a
    create :: Create (BBOCG a)
create a
n_ a
ca_ a
c_ a
o_ a
cg_ AA
aa = coerce :: forall a b. Coercible a b => a -> b
coerce forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (nr :: * -> *) (car :: * -> *) (cr :: * -> *) a.
nr a -> car a -> cr a -> AminoAcid nr car cr a
AminoAcid (forall (f :: * -> *) a. Applicative f => a -> f a
pure a
n_) (forall (r :: * -> *) a. a -> r a -> Env r a
Env a
ca_ (forall a. a -> AA -> CG a
CG a
cg_ AA
aa)) (forall (r :: * -> *) a. a -> r a -> Env r a
Env a
c_ (forall (f :: * -> *) a. Applicative f => a -> f a
pure a
o_))

instance Createable (BBOR a) where
    type Create (BBOR a) = a -> a -> a -> a -> Radical a -> BBOR a
    create :: Create (BBOR a)
create a
n_ a
ca_ a
c_ a
o_ Radical a
r = coerce :: forall a b. Coercible a b => a -> b
coerce forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (nr :: * -> *) (car :: * -> *) (cr :: * -> *) a.
nr a -> car a -> cr a -> AminoAcid nr car cr a
AminoAcid (forall (f :: * -> *) a. Applicative f => a -> f a
pure a
n_) (forall (r :: * -> *) a. a -> r a -> Env r a
Env a
ca_ Radical a
r) (forall (r :: * -> *) a. a -> r a -> Env r a
Env a
c_ (forall (f :: * -> *) a. Applicative f => a -> f a
pure a
o_))

instance Createable (BBOXTR a) where
    type Create (BBOXTR a) = a -> a -> a -> a -> a -> Radical a -> BBOXTR a
    create :: Create (BBOXTR a)
create a
n_ a
ca_ a
c_ a
o_ a
oxt_ Radical a
r = coerce :: forall a b. Coercible a b => a -> b
coerce forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (nr :: * -> *) (car :: * -> *) (cr :: * -> *) a.
nr a -> car a -> cr a -> AminoAcid nr car cr a
AminoAcid (forall (f :: * -> *) a. Applicative f => a -> f a
pure a
n_) (forall (r :: * -> *) a. a -> r a -> Env r a
Env a
ca_ Radical a
r) (forall (r :: * -> *) a. a -> r a -> Env r a
Env a
c_ (forall a. a -> a -> OXT a
OXT a
o_ a
oxt_))

instance Createable (BBORH a) where
    type Create (BBORH a) = a -> a -> a -> a -> Radical a -> BBORH a
    create :: Create (BBORH a)
create a
n_ a
ca_ a
c_ a
o_ Radical a
r = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (r :: * -> *) a. a -> r a -> Env r a
Env [] forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (nr :: * -> *) (car :: * -> *) (cr :: * -> *) a.
nr a -> car a -> cr a -> AminoAcid nr car cr a
AminoAcid (forall (f :: * -> *) a. Applicative f => a -> f a
pure a
n_) (forall (r :: * -> *) a. a -> r a -> Env r a
Env a
ca_ Radical a
r) (forall (r :: * -> *) a. a -> r a -> Env r a
Env a
c_ (forall (f :: * -> *) a. Applicative f => a -> f a
pure a
o_))

instance Createable (BBOXTRH a) where
    type Create (BBOXTRH a) = a -> a -> a -> a -> a -> Radical a -> BBOXTRH a
    create :: Create (BBOXTRH a)
create a
n_ a
ca_ a
c_ a
o_ a
oxt_ Radical a
r = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (r :: * -> *) a. a -> r a -> Env r a
Env [] forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (nr :: * -> *) (car :: * -> *) (cr :: * -> *) a.
nr a -> car a -> cr a -> AminoAcid nr car cr a
AminoAcid (forall (f :: * -> *) a. Applicative f => a -> f a
pure a
n_) (forall (r :: * -> *) a. a -> r a -> Env r a
Env a
ca_ Radical a
r) (forall (r :: * -> *) a. a -> r a -> Env r a
Env a
c_ (forall a. a -> a -> OXT a
OXT a
o_ a
oxt_))

-------------------------------------------------------------------------------
-- HasRadical
-------------------------------------------------------------------------------

-- | Has lens to observe, set and modify radicals
--
class Functor r => HasRadical r where
    type RadicalType r a :: Type
    -- | Lens for radical atom or group
    --
    radical :: (Functor f, Functor g) => Lens' (AminoAcid f (Env r) g a) (RadicalType r a)

instance HasRadical (Const x) where
    type RadicalType (Const x) a = x
    radical :: forall (f :: * -> *) (g :: * -> *) a.
(Functor f, Functor g) =>
Lens' (AminoAcid f (Env (Const x)) g a) (RadicalType (Const x) a)
radical = forall (nr :: * -> *) (car1 :: * -> *) (cr :: * -> *) a
       (car2 :: * -> *).
Lens
  (AminoAcid nr car1 cr a) (AminoAcid nr car2 cr a) (car1 a) (car2 a)
ca' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (r1 :: * -> *) a (r2 :: * -> *).
Lens (Env r1 a) (Env r2 a) (r1 a) (r2 a)
environment forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s t a b. (Coercible s a, Coercible t b) => Iso s t a b
coerced

instance HasRadical Radical where
    type RadicalType Radical a = Radical a
    radical :: forall (f :: * -> *) (g :: * -> *) a.
(Functor f, Functor g) =>
Lens' (AminoAcid f (Env Radical) g a) (RadicalType Radical a)
radical = forall (nr :: * -> *) (car1 :: * -> *) (cr :: * -> *) a
       (car2 :: * -> *).
Lens
  (AminoAcid nr car1 cr a) (AminoAcid nr car2 cr a) (car1 a) (car2 a)
ca' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (r1 :: * -> *) a (r2 :: * -> *).
Lens (Env r1 a) (Env r2 a) (r1 a) (r2 a)
environment

instance HasRadical CG where
    type RadicalType CG a = a
    radical :: forall (f :: * -> *) (g :: * -> *) a.
(Functor f, Functor g) =>
Lens' (AminoAcid f (Env CG) g a) (RadicalType CG a)
radical = forall (nr :: * -> *) (car1 :: * -> *) (cr :: * -> *) a
       (car2 :: * -> *).
Lens
  (AminoAcid nr car1 cr a) (AminoAcid nr car2 cr a) (car1 a) (car2 a)
ca' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (r1 :: * -> *) a (r2 :: * -> *).
Lens (Env r1 a) (Env r2 a) (r1 a) (r2 a)
environment forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a1 a2. Lens (CG a1) (CG a2) a1 a2
cg'

instance HasRadical Identity where
    type RadicalType Identity a = a
    radical :: forall (f :: * -> *) (g :: * -> *) a.
(Functor f, Functor g) =>
Lens' (AminoAcid f (Env Identity) g a) (RadicalType Identity a)
radical = forall (nr :: * -> *) (car1 :: * -> *) (cr :: * -> *) a
       (car2 :: * -> *).
Lens
  (AminoAcid nr car1 cr a) (AminoAcid nr car2 cr a) (car1 a) (car2 a)
ca' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (r1 :: * -> *) a (r2 :: * -> *).
Lens (Env r1 a) (Env r2 a) (r1 a) (r2 a)
environment forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s t a b. (Coercible s a, Coercible t b) => Iso s t a b
coerced

-------------------------------------------------------------------------------
-- HasRadicalType
-------------------------------------------------------------------------------

-- | Has lens to observe radical types
--
class Functor r => HasRadicalType r where
    -- | Getter for radical type
    --
    radicalType :: (Functor f, Functor g) => Getting AA (AminoAcid f (Env r) g a) AA

instance HasRadicalType (Const AA) where
    radicalType :: forall (f :: * -> *) (g :: * -> *) a.
(Functor f, Functor g) =>
Getting AA (AminoAcid f (Env (Const AA)) g a) AA
radicalType = forall (nr :: * -> *) (car1 :: * -> *) (cr :: * -> *) a
       (car2 :: * -> *).
Lens
  (AminoAcid nr car1 cr a) (AminoAcid nr car2 cr a) (car1 a) (car2 a)
ca' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (r1 :: * -> *) a (r2 :: * -> *).
Lens (Env r1 a) (Env r2 a) (r1 a) (r2 a)
environment forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s t a b. (Coercible s a, Coercible t b) => Iso s t a b
coerced

instance HasRadicalType CG where
    radicalType :: forall (f :: * -> *) (g :: * -> *) a.
(Functor f, Functor g) =>
Getting AA (AminoAcid f (Env CG) g a) AA
radicalType = forall (nr :: * -> *) (car1 :: * -> *) (cr :: * -> *) a
       (car2 :: * -> *).
Lens
  (AminoAcid nr car1 cr a) (AminoAcid nr car2 cr a) (car1 a) (car2 a)
ca' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (r1 :: * -> *) a (r2 :: * -> *).
Lens (Env r1 a) (Env r2 a) (r1 a) (r2 a)
environment forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Lens' (CG a) AA
radical' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s t a b. (Coercible s a, Coercible t b) => Iso s t a b
coerced

instance HasRadicalType Radical where
    radicalType :: forall (f :: * -> *) (g :: * -> *) a.
(Functor f, Functor g) =>
Getting AA (AminoAcid f (Env Radical) g a) AA
radicalType = forall (nr :: * -> *) (car1 :: * -> *) (cr :: * -> *) a
       (car2 :: * -> *).
Lens
  (AminoAcid nr car1 cr a) (AminoAcid nr car2 cr a) (car1 a) (car2 a)
ca' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (r1 :: * -> *) a (r2 :: * -> *).
Lens (Env r1 a) (Env r2 a) (r1 a) (r2 a)
environment forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to forall a. Radical a -> AA
rad2rad

-------------------------------------------------------------------------------
-- Has some atom
-------------------------------------------------------------------------------

-- | Has lens to observe, set and modify ca_ atom
--
class Functor r => HasCA r where
    -- | Lens for ca_ atom
    --
    ca :: (Functor f, Functor g) => Lens' (AminoAcid f r g a) a

instance HasCA Identity where
    ca :: forall (f :: * -> *) (g :: * -> *) a.
(Functor f, Functor g) =>
Lens' (AminoAcid f Identity g a) a
ca = forall (nr :: * -> *) (car1 :: * -> *) (cr :: * -> *) a
       (car2 :: * -> *).
Lens
  (AminoAcid nr car1 cr a) (AminoAcid nr car2 cr a) (car1 a) (car2 a)
ca' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s t a b. (Coercible s a, Coercible t b) => Iso s t a b
coerced

instance Functor f => HasCA (Env f) where
    ca :: forall (f :: * -> *) (g :: * -> *) a.
(Functor f, Functor g) =>
Lens' (AminoAcid f (Env f) g a) a
ca = forall (nr :: * -> *) (car1 :: * -> *) (cr :: * -> *) a
       (car2 :: * -> *).
Lens
  (AminoAcid nr car1 cr a) (AminoAcid nr car2 cr a) (car1 a) (car2 a)
ca' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (r :: * -> *) a. Lens' (Env r a) a
atom'

-- | Has lens to observe, set and modify c_ atom
--
class Functor r => HasC r where
    -- | Lens for c_ atom
    --
    c :: (Functor f, Functor g) => Lens' (AminoAcid f g r a) a

instance HasC Identity where
    c :: forall (f :: * -> *) (g :: * -> *) a.
(Functor f, Functor g) =>
Lens' (AminoAcid f g Identity a) a
c = forall (nr :: * -> *) (car :: * -> *) (cr1 :: * -> *) a
       (cr2 :: * -> *).
Lens
  (AminoAcid nr car cr1 a) (AminoAcid nr car cr2 a) (cr1 a) (cr2 a)
c' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s t a b. (Coercible s a, Coercible t b) => Iso s t a b
coerced

instance Functor f => HasC (Env f) where
    c :: forall (f :: * -> *) (g :: * -> *) a.
(Functor f, Functor g) =>
Lens' (AminoAcid f g (Env f) a) a
c = forall (nr :: * -> *) (car :: * -> *) (cr1 :: * -> *) a
       (cr2 :: * -> *).
Lens
  (AminoAcid nr car cr1 a) (AminoAcid nr car cr2 a) (cr1 a) (cr2 a)
c' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (r :: * -> *) a. Lens' (Env r a) a
atom'

-- | Has lens to observe, set and modify o_ atom
--
class Functor r => HasO r where
    -- | Lens for o_ atom
    --
    o :: (Functor f, Functor g) => Lens' (AminoAcid f g (Env r) a) a

instance HasO Identity where
    o :: forall (f :: * -> *) (g :: * -> *) a.
(Functor f, Functor g) =>
Lens' (AminoAcid f g (Env Identity) a) a
o = forall (nr :: * -> *) (car :: * -> *) (cr1 :: * -> *) a
       (cr2 :: * -> *).
Lens
  (AminoAcid nr car cr1 a) (AminoAcid nr car cr2 a) (cr1 a) (cr2 a)
c' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (r1 :: * -> *) a (r2 :: * -> *).
Lens (Env r1 a) (Env r2 a) (r1 a) (r2 a)
environment forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s t a b. (Coercible s a, Coercible t b) => Iso s t a b
coerced

instance HasO OXT where
    o :: forall (f :: * -> *) (g :: * -> *) a.
(Functor f, Functor g) =>
Lens' (AminoAcid f g (Env OXT) a) a
o = forall (nr :: * -> *) (car :: * -> *) (cr1 :: * -> *) a
       (cr2 :: * -> *).
Lens
  (AminoAcid nr car cr1 a) (AminoAcid nr car cr2 a) (cr1 a) (cr2 a)
c' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (r1 :: * -> *) a (r2 :: * -> *).
Lens (Env r1 a) (Env r2 a) (r1 a) (r2 a)
environment forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Lens' (OXT a) a
o'

-- | Has lens to observe, set and modify OXT atom
--
class Functor r => HasOXT r where
    -- | Lens for OXT atom
    --
    oxt :: (Functor f, Functor g) => Lens' (AminoAcid f g (Env r) a) a

instance HasOXT OXT where
    oxt :: forall (f :: * -> *) (g :: * -> *) a.
(Functor f, Functor g) =>
Lens' (AminoAcid f g (Env OXT) a) a
oxt = forall (nr :: * -> *) (car :: * -> *) (cr1 :: * -> *) a
       (cr2 :: * -> *).
Lens
  (AminoAcid nr car cr1 a) (AminoAcid nr car cr2 a) (cr1 a) (cr2 a)
c' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (r1 :: * -> *) a (r2 :: * -> *).
Lens (Env r1 a) (Env r2 a) (r1 a) (r2 a)
environment forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Lens' (OXT a) a
oxt'

-- | Has lens to observe, set and modify n_ atom
--
class Functor r => HasN r where
    -- | Lens for n_ atom
    --
    n :: (Functor f, Functor g) => Lens' (AminoAcid r f g a) a

instance HasN Identity where
    n :: forall (f :: * -> *) (g :: * -> *) a.
(Functor f, Functor g) =>
Lens' (AminoAcid Identity f g a) a
n = forall (nr1 :: * -> *) (car :: * -> *) (cr :: * -> *) a
       (nr2 :: * -> *).
Lens
  (AminoAcid nr1 car cr a) (AminoAcid nr2 car cr a) (nr1 a) (nr2 a)
n' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s t a b. (Coercible s a, Coercible t b) => Iso s t a b
coerced

instance Functor f => HasN (Env f) where
    n :: forall (f :: * -> *) (g :: * -> *) a.
(Functor f, Functor g) =>
Lens' (AminoAcid (Env f) f g a) a
n = forall (nr1 :: * -> *) (car :: * -> *) (cr :: * -> *) a
       (nr2 :: * -> *).
Lens
  (AminoAcid nr1 car cr a) (AminoAcid nr2 car cr a) (nr1 a) (nr2 a)
n' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (r :: * -> *) a. Lens' (Env r a) a
atom'

-- | Lens to get atom from some enviroment
--
class Functor f => HasAtom f where
    -- | Lens for exact atom get
    --
    atom :: Lens' (f a) a

instance HasAtom Identity where
    atom :: forall a. Lens' (Identity a) a
atom = forall s t a b. (Coercible s a, Coercible t b) => Iso s t a b
coerced

instance Functor r => HasAtom (Env r) where
    atom :: forall a. Lens' (Env r a) a
atom = forall (r :: * -> *) a. Lens' (Env r a) a
atom'

-- | Lens to get hydrogens from hydrated atom
--
hydrogens :: Lens' (Env [] a) [a]
hydrogens :: forall a. Lens' (Env [] a) [a]
hydrogens = forall (r1 :: * -> *) a (r2 :: * -> *).
Lens (Env r1 a) (Env r2 a) (r1 a) (r2 a)
environment

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

-- | Lens to get Symbol from every suitable amino acid
--
instance (Functor nr, HasRadicalType car, Functor cr) => Symbol (AminoAcid nr (Env car) cr a) where
    symbol :: AminoAcid nr (Env car) cr a -> Char
symbol = forall a. Symbol a => a -> Char
symbol forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall s a. s -> Getting a s a -> a
^. forall (r :: * -> *) (f :: * -> *) (g :: * -> *) a.
(HasRadicalType r, Functor f, Functor g) =>
Getting AA (AminoAcid f (Env r) g a) AA
radicalType)

-- | Symbol encoding
--
instance Symbol AA where
    symbol :: AA -> Char
symbol AA
ALA = Char
'A'
    symbol AA
CYS = Char
'C'
    symbol AA
ASP = Char
'D'
    symbol AA
GLU = Char
'E'
    symbol AA
PHE = Char
'F'
    symbol AA
GLY = Char
'G'
    symbol AA
HIS = Char
'H'
    symbol AA
ILE = Char
'I'
    symbol AA
LYS = Char
'K'
    symbol AA
LEU = Char
'L'
    symbol AA
MET = Char
'M'
    symbol AA
ASN = Char
'N'
    symbol AA
PRO = Char
'P'
    symbol AA
GLN = Char
'Q'
    symbol AA
ARG = Char
'R'
    symbol AA
SER = Char
'S'
    symbol AA
THR = Char
'T'
    symbol AA
VAL = Char
'V'
    symbol AA
TRP = Char
'W'
    symbol AA
TYR = Char
'Y'

-- | Parse symbol encoding
--
instance FromSymbol AA where
    fromSymbolE :: Char -> Either Char AA
fromSymbolE Char
'A' = forall a b. b -> Either a b
Right AA
ALA
    fromSymbolE Char
'C' = forall a b. b -> Either a b
Right AA
CYS
    fromSymbolE Char
'D' = forall a b. b -> Either a b
Right AA
ASP
    fromSymbolE Char
'E' = forall a b. b -> Either a b
Right AA
GLU
    fromSymbolE Char
'F' = forall a b. b -> Either a b
Right AA
PHE
    fromSymbolE Char
'G' = forall a b. b -> Either a b
Right AA
GLY
    fromSymbolE Char
'H' = forall a b. b -> Either a b
Right AA
HIS
    fromSymbolE Char
'I' = forall a b. b -> Either a b
Right AA
ILE
    fromSymbolE Char
'K' = forall a b. b -> Either a b
Right AA
LYS
    fromSymbolE Char
'L' = forall a b. b -> Either a b
Right AA
LEU
    fromSymbolE Char
'M' = forall a b. b -> Either a b
Right AA
MET
    fromSymbolE Char
'N' = forall a b. b -> Either a b
Right AA
ASN
    fromSymbolE Char
'P' = forall a b. b -> Either a b
Right AA
PRO
    fromSymbolE Char
'Q' = forall a b. b -> Either a b
Right AA
GLN
    fromSymbolE Char
'R' = forall a b. b -> Either a b
Right AA
ARG
    fromSymbolE Char
'S' = forall a b. b -> Either a b
Right AA
SER
    fromSymbolE Char
'T' = forall a b. b -> Either a b
Right AA
THR
    fromSymbolE Char
'V' = forall a b. b -> Either a b
Right AA
VAL
    fromSymbolE Char
'W' = forall a b. b -> Either a b
Right AA
TRP
    fromSymbolE Char
'Y' = forall a b. b -> Either a b
Right AA
TYR
    fromSymbolE Char
ch  = forall a b. a -> Either a b
Left Char
ch

-- | Three symbols encoding
--
instance ThreeSymbols AA where
    threeSymbols :: AA -> Text
threeSymbols AA
ALA = Text
"ALA"
    threeSymbols AA
CYS = Text
"CYS"
    threeSymbols AA
ASP = Text
"ASP"
    threeSymbols AA
GLU = Text
"GLU"
    threeSymbols AA
PHE = Text
"PHE"
    threeSymbols AA
GLY = Text
"GLY"
    threeSymbols AA
HIS = Text
"HIS"
    threeSymbols AA
ILE = Text
"ILE"
    threeSymbols AA
LYS = Text
"LYS"
    threeSymbols AA
LEU = Text
"LEU"
    threeSymbols AA
MET = Text
"MET"
    threeSymbols AA
ASN = Text
"ASN"
    threeSymbols AA
PRO = Text
"PRO"
    threeSymbols AA
GLN = Text
"GLN"
    threeSymbols AA
ARG = Text
"ARG"
    threeSymbols AA
SER = Text
"SER"
    threeSymbols AA
THR = Text
"THR"
    threeSymbols AA
VAL = Text
"VAL"
    threeSymbols AA
TRP = Text
"TRP"
    threeSymbols AA
TYR = Text
"TYR"

-- | Parse three symbols encoding
--
instance FromThreeSymbols AA where
    fromThreeSymbols :: Text -> Maybe AA
fromThreeSymbols Text
"ALA" = forall a. a -> Maybe a
Just AA
ALA
    fromThreeSymbols Text
"CYS" = forall a. a -> Maybe a
Just AA
CYS
    fromThreeSymbols Text
"ASP" = forall a. a -> Maybe a
Just AA
ASP
    fromThreeSymbols Text
"GLU" = forall a. a -> Maybe a
Just AA
GLU
    fromThreeSymbols Text
"PHE" = forall a. a -> Maybe a
Just AA
PHE
    fromThreeSymbols Text
"GLY" = forall a. a -> Maybe a
Just AA
GLY
    fromThreeSymbols Text
"HIS" = forall a. a -> Maybe a
Just AA
HIS
    fromThreeSymbols Text
"ILE" = forall a. a -> Maybe a
Just AA
ILE
    fromThreeSymbols Text
"LYS" = forall a. a -> Maybe a
Just AA
LYS
    fromThreeSymbols Text
"LEU" = forall a. a -> Maybe a
Just AA
LEU
    fromThreeSymbols Text
"MET" = forall a. a -> Maybe a
Just AA
MET
    fromThreeSymbols Text
"ASN" = forall a. a -> Maybe a
Just AA
ASN
    fromThreeSymbols Text
"PRO" = forall a. a -> Maybe a
Just AA
PRO
    fromThreeSymbols Text
"GLN" = forall a. a -> Maybe a
Just AA
GLN
    fromThreeSymbols Text
"ARG" = forall a. a -> Maybe a
Just AA
ARG
    fromThreeSymbols Text
"SER" = forall a. a -> Maybe a
Just AA
SER
    fromThreeSymbols Text
"THR" = forall a. a -> Maybe a
Just AA
THR
    fromThreeSymbols Text
"VAL" = forall a. a -> Maybe a
Just AA
VAL
    fromThreeSymbols Text
"TRP" = forall a. a -> Maybe a
Just AA
TRP
    fromThreeSymbols Text
"TYR" = forall a. a -> Maybe a
Just AA
TYR
    fromThreeSymbols Text
_     = forall a. Maybe a
Nothing

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

instance {-# OVERLAPPING #-} IsString [AA] where
    fromString :: String -> [AA]
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 [AA]
l -> [AA]
l
            Left Char
e  -> forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"Bio.Protein.AminoAcid.Instances: could not read aminoacid " forall a. Semigroup a => a -> a -> a
<> [Char
e]

instance IsString (Array Int AA) where
    fromString :: String -> Array Int AA
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