diff --git a/Biobase/GeneticCodes.hs b/Biobase/GeneticCodes.hs
--- a/Biobase/GeneticCodes.hs
+++ b/Biobase/GeneticCodes.hs
@@ -25,22 +25,22 @@
 
 
 codeByTableID
-  ∷ (MonadError String m)
-  ⇒ [TranslationTable c a]
-  → Int
-  → m (TranslationTable c a)
+  :: (MonadError String m)
+  => [TranslationTable c a]
+  -> Int
+  -> m (TranslationTable c a)
 codeByTableID ts i
   = maybe (throwError $ printf "No TranslationTable with ID %d found!" i) return
-  $ find (\t → t^.tableID == i) ts
+  $ find (\t -> t^.tableID == i) ts
 
 codeByTableNameInfix
-  ∷ (MonadError String m)
-  ⇒ [TranslationTable c a]
-  → Text
-  → m (TranslationTable c a)
+  :: (MonadError String m)
+  => [TranslationTable c a]
+  -> Text
+  -> m (TranslationTable c a)
 codeByTableNameInfix ts n
   = maybe (throwError $ printf "No TranslationTable with Name infix %s found!" $ unpack n) return
-  $ find (\t → n `isInfixOf` (t^.tableName)) ts
+  $ find (\t -> n `isInfixOf` (t^.tableName)) ts
 
 -- | If the given filepath exists, then we try to load the genetic table from
 -- the file. This will fail if there is not exactly one genetic table there. If
@@ -54,17 +54,17 @@
 -- is returned.
 
 fromFileOrCached
-  ∷ (MonadIO m, MonadError String m)
-  ⇒ FilePath
-  → m (TranslationTable Char Char)
+  :: (MonadIO m, MonadError String m)
+  => FilePath
+  -> m (TranslationTable Char Char)
 fromFileOrCached fp = do
   dfe ← liftIO $ doesFileExist fp
-  if | fp == "list" → do
+  if | fp == "list" -> do
           mapM_ (liftIO . uncurry (printf "%3d %s\n")) [ (t^.tableID,t^.tableName) | t ← geneticCodes ]
           liftIO exitSuccess
-     | dfe → fromFile fp >>= \case
-         [x] → return x
-         xs  → throwError $ fp ++ " should contain exactly one translation table!"
-     | [(k,"")] ← reads fp → codeByTableID geneticCodes k
-     | otherwise → codeByTableNameInfix geneticCodes $ pack fp
+     | dfe -> fromFile fp >>= \case
+         [x] -> return x
+         xs  -> throwError $ fp ++ " should contain exactly one translation table!"
+     | [(k,"")] <- reads fp -> codeByTableID geneticCodes k
+     | otherwise -> codeByTableNameInfix geneticCodes $ pack fp
 
diff --git a/Biobase/GeneticCodes/Embedded.hs b/Biobase/GeneticCodes/Embedded.hs
--- a/Biobase/GeneticCodes/Embedded.hs
+++ b/Biobase/GeneticCodes/Embedded.hs
@@ -8,9 +8,9 @@
 import Biobase.GeneticCodes.Import
 import Biobase.GeneticCodes.Types
 
-geneticCodesFile ∷ ByteString
-geneticCodesFile = $(embedFile "sources/translation-tables")
+geneticCodesFile :: ByteString
+geneticCodesFile = $(makeRelativeToProject "sources/translation-tables" >>= embedFile)
 
-geneticCodes ∷ [TranslationTable Char Char]
+geneticCodes :: [TranslationTable Char Char]
 geneticCodes = either error id . runExcept $ fromByteString geneticCodesFile
 
diff --git a/Biobase/GeneticCodes/Import.hs b/Biobase/GeneticCodes/Import.hs
--- a/Biobase/GeneticCodes/Import.hs
+++ b/Biobase/GeneticCodes/Import.hs
@@ -30,25 +30,25 @@
 -- the error and exit with a failure.
 
 fromFile
-  ∷ (MonadIO m, MonadError String m)
-  ⇒ FilePath
-  → m [TranslationTable Char Char]
+  :: (MonadIO m, MonadError String m)
+  => FilePath
+  -> m [TranslationTable Char Char]
 fromFile fp = (liftIO $ BS.readFile fp) >>= fromByteString
 
 -- | Parse a ByteString with translation tables.
 
 fromByteString
-  ∷ (MonadError String m)
-  ⇒ ByteString
-  → m [TranslationTable Char Char]
+  :: (MonadError String m)
+  => ByteString
+  -> m [TranslationTable Char Char]
 fromByteString bs = case runParser (some parseTranslationTable) "" (decodeUtf8 bs) of
-    -- Left err → throwError $ parseErrorPretty err -- megaparsec 6.x
-    Left err → throwError $ errorBundlePretty err   -- megaparsec 7.x
-    Right rs → return rs
+    -- Left err -> throwError $ parseErrorPretty err -- megaparsec 6.x
+    Left err -> throwError $ errorBundlePretty err   -- megaparsec 7.x
+    Right rs -> return rs
 
 -- | Parses a single translation table.
 
-parseTranslationTable ∷ TTParser (TranslationTable Char Char)
+parseTranslationTable :: TTParser (TranslationTable Char Char)
 parseTranslationTable = do
   (i,hdr) ← parseHeader
   aas     ← parseData "amino acids"
@@ -63,14 +63,14 @@
 
 -- | Parse the header, returning the Identifier and the name of the table.
 
-parseHeader ∷ TTParser (Int,Text)
+parseHeader :: TTParser (Int,Text)
 parseHeader
   = (,) <$> (fromIntegral <$> lexeme MC.space decimal)
   <* char ':' <* MC.space
   <*> takeWhileP Nothing (/= '\n')
   <* MC.space
 
-parseData ∷ Text → TTParser String
+parseData :: Text -> TTParser String
 parseData t
   = string' t <* MC.space
   *> (unpack <$> takeP Nothing 64)
diff --git a/Biobase/GeneticCodes/Translation.hs b/Biobase/GeneticCodes/Translation.hs
--- a/Biobase/GeneticCodes/Translation.hs
+++ b/Biobase/GeneticCodes/Translation.hs
@@ -25,13 +25,16 @@
 
 class Translation t where
   -- | Defines the target type for a given translation input.
-  type TargetType t ∷ *
+  type TargetType t :: *
   -- | Type of the nucleotide characters.
-  type CodonType t ∷ *
+  type CodonType t :: *
   -- | Type of the amino acid characters.
-  type AAType t ∷ *
+  type AAType t :: *
   -- | Translate from a given type of sequence @t@ into the target type.
-  translate ∷ TranslationTable (CodonType t) (AAType t) → t → TargetType t
+  translate :: TranslationTable (CodonType t) (AAType t) -> t -> TargetType t
+  -- | This function works just like @translate@ but with an important difference of creating a
+  -- target sequence that contains all possible frames. The index @mod 3@ yields the current frame.
+  translateAllFrames :: TranslationTable (CodonType t) (AAType t) -> t -> TargetType t
 
 -- | Very simple translation of individual base triplets.
 
@@ -41,6 +44,8 @@
   type AAType      (Codon Char) = Char
   translate tbl t = maybe 'X' _aminoAcid $ M.lookup t (tbl^.codonToAminoAcid)
   {-# Inline translate #-}
+  translateAllFrames = translate
+  {-# Inline translateAllFrames #-}
 
 -- | Strings of characters are normally very inconvenient but useful in
 -- backtracking cases. Fully assumes that the alphabet is DNA. Ignores
@@ -55,6 +60,14 @@
               | otherwise = []
               where (hd,tl) = splitAt 3 xs
     in  go
+  {-# Inlinable translate #-}
+  translateAllFrames tbl = go []
+    where go _     []     = []
+          -- first two AA are unknown @?@ since the codon has not been established at this point.
+          go []    (x:xs) = '?' : go [x] xs
+          go [p]   (x:xs) = '?' : go [p,x] xs
+          go [p,q] (x:xs) = translate tbl (Codon p q x) : go [q,x] xs
+  {-# Inlinable translateAllFrames #-}
 
 -- | Translation of @BioSequence DNA@. The translation tables assume DNA
 -- triplets anyway. Biologically there should be a transcription step in
@@ -67,4 +80,10 @@
   translate tbl (BioSequence xs) =
     let go k = Just (translate tbl $ Codon (BS.index xs k) (BS.index xs (k+1)) (BS.index xs (k+2)) ,k+3)
     in  BioSequence . fst $ BS.unfoldrN (BS.length xs `div` 3) go 0
+  {-# Inlinable translate #-}
+  translateAllFrames tbl (BioSequence xs) = BioSequence . fst $ BS.unfoldrN (BS.length xs) go 0
+    where go 0 = Just ('?', 1)
+          go 1 = Just ('?', 2)
+          go k = Just (translate tbl $ Codon (BS.index xs (k-2)) (BS.index xs (k-1)) (BS.index xs k), k+1)
+  {-# Inlinable translateAllFrames #-}
 
diff --git a/Biobase/GeneticCodes/Types.hs b/Biobase/GeneticCodes/Types.hs
--- a/Biobase/GeneticCodes/Types.hs
+++ b/Biobase/GeneticCodes/Types.hs
@@ -13,31 +13,31 @@
 
 
 data TranslationElement c a = TranslationElement
-  { _baseCodon    ∷ !(Codon c)
-  , _isStartCodon ∷ !Bool
-  , _aminoAcid    ∷ !a
+  { _baseCodon    :: !(Codon c)
+  , _isStartCodon :: !Bool
+  , _aminoAcid    :: !a
   }
   deriving (Show)
 makeLenses ''TranslationElement
 
 data TranslationTable c a = TranslationTable
-  { _codonToAminoAcid  ∷ !(Map (Codon c) (TranslationElement c a))
-  , _aminoAcidtoCodons ∷ !(Map a [TranslationElement c a])
-  , _tableID           ∷ !Int
-  , _tableName         ∷ !Text
+  { _codonToAminoAcid  :: !(Map (Codon c) (TranslationElement c a))
+  , _aminoAcidtoCodons :: !(Map a [TranslationElement c a])
+  , _tableID           :: !Int
+  , _tableName         :: !Text
   }
   deriving (Show)
 makeLenses ''TranslationTable
 
 genTranslationTable
-  ∷ (Ord c, Ord a)
-  ⇒ Int
+  :: (Ord c, Ord a)
+  => Int
   -- ^ table identifier
-  → Text
+  -> Text
   -- ^ table hdr / table name
-  → [TranslationElement c a]
+  -> [TranslationElement c a]
   -- ^ known translation elements (should be @4^3@ but is not checked)
-  → TranslationTable c a
+  -> TranslationTable c a
   -- ^ finished translation table
 {-# Inlinable genTranslationTable #-}
 genTranslationTable i hdr xs = TranslationTable
diff --git a/BiobaseENA.cabal b/BiobaseENA.cabal
--- a/BiobaseENA.cabal
+++ b/BiobaseENA.cabal
@@ -1,17 +1,17 @@
 Cabal-version:  2.2
 Name:           BiobaseENA
-Version:        0.0.0.1
+Version:        0.0.0.2
 License:        BSD-3-Clause
 License-file:   LICENSE
 Author:         Christian Hoener zu Siederdissen
 Maintainer:     choener@bioinf.uni-leipzig.de
-Copyright:      Christian Hoener zu Siederdissen, 2019
+Copyright:      Christian Hoener zu Siederdissen, 2020-2021
 homepage:       https://github.com/choener/BiobaseENA
 bug-reports:    https://github.com/choener/BiobaseENA/issues
 Stability:      Experimental
 Category:       Data
 Build-type:     Simple
-tested-with:    GHC == 8.4.4
+tested-with:    GHC == 8.8, GHC == 8.10, GHC == 9.0
 Synopsis:       European Nucleotide Archive data
 Description:
                 Provides data (and later API) access to the European Nucleotide Archive.
@@ -39,7 +39,7 @@
                , vector                   >= 0.10
                , vector-th-unbox          >= 0.2
                --
-               , BiobaseTypes             == 0.2.0.*
+               , BiobaseTypes             == 0.2.1.*
   ghc-options:
     -O2
     -funbox-strict-fields
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[![Build Status](https://travis-ci.org/choener/BiobaseENA.svg?branch=master)](https://travis-ci.org/choener/BiobaseENA)
+![github action: master](https://github.com/choener/BiobaseENA/actions/workflows/action.yml/badge.svg)
 
 # BiobaseENA
 
