{-# LANGUAGE OverloadedLists #-}

module Data.Gibberish.Types
  ( GenPasswordOpts (..),
    GenPassphraseOpts (..),
    Language (..),
    TrigraphConfig (..),
    Unigram (..),
    Digram (..),
    Trigram (..),
    Frequency (..),
    Frequencies (..),
    Trigraph (..),
    Word (..),
  ) where

import Control.DeepSeq (NFData)
import Data.Aeson (FromJSON (..), FromJSONKey (..), ToJSON (..), ToJSONKey (..))
import Data.Aeson qualified as Aeson
import Data.Aeson.Types (FromJSONKeyFunction (..), Parser (), toJSONKeyText)
import Data.Map (Map ())
import Data.Text (Text ())
import GHC.Generics (Generic ())
import TextShow (TextShow (..), fromString)
import Prelude hiding (Word ())

-- | Password generation options
data GenPasswordOpts = GenPasswordOpts
  { -- | Include capitals?
    GenPasswordOpts -> Bool
woptsCapitals :: !Bool,
    -- | Include numerals?
    GenPasswordOpts -> Bool
woptsDigits :: !Bool,
    -- | Include special characters?
    GenPasswordOpts -> Bool
woptsSpecials :: !Bool,
    -- | The trigraph to use
    GenPasswordOpts -> Trigraph
woptsTrigraph :: Trigraph,
    -- | The length of the password
    GenPasswordOpts -> Int
woptsLength :: !Int
  }
  deriving stock (GenPasswordOpts -> GenPasswordOpts -> Bool
(GenPasswordOpts -> GenPasswordOpts -> Bool)
-> (GenPasswordOpts -> GenPasswordOpts -> Bool)
-> Eq GenPasswordOpts
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: GenPasswordOpts -> GenPasswordOpts -> Bool
== :: GenPasswordOpts -> GenPasswordOpts -> Bool
$c/= :: GenPasswordOpts -> GenPasswordOpts -> Bool
/= :: GenPasswordOpts -> GenPasswordOpts -> Bool
Eq, Int -> GenPasswordOpts -> ShowS
[GenPasswordOpts] -> ShowS
GenPasswordOpts -> String
(Int -> GenPasswordOpts -> ShowS)
-> (GenPasswordOpts -> String)
-> ([GenPasswordOpts] -> ShowS)
-> Show GenPasswordOpts
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> GenPasswordOpts -> ShowS
showsPrec :: Int -> GenPasswordOpts -> ShowS
$cshow :: GenPasswordOpts -> String
show :: GenPasswordOpts -> String
$cshowList :: [GenPasswordOpts] -> ShowS
showList :: [GenPasswordOpts] -> ShowS
Show)

-- | Passphrase generation options
data GenPassphraseOpts = GenPassphraseOpts
  { -- | Include capitals?
    GenPassphraseOpts -> Bool
poptsCapitals :: !Bool,
    -- | Include numerals?
    GenPassphraseOpts -> Bool
poptsDigits :: !Bool,
    -- | Include special characters?
    GenPassphraseOpts -> Bool
poptsSpecials :: !Bool,
    -- | The trigraph to use
    GenPassphraseOpts -> Trigraph
poptsTrigraph :: Trigraph,
    -- | The mininum length of each word
    GenPassphraseOpts -> Int
poptsMinLength :: !Int,
    -- | The maximum length of each word
    GenPassphraseOpts -> Int
poptsMaxLength :: !Int
  }
  deriving stock (GenPassphraseOpts -> GenPassphraseOpts -> Bool
(GenPassphraseOpts -> GenPassphraseOpts -> Bool)
-> (GenPassphraseOpts -> GenPassphraseOpts -> Bool)
-> Eq GenPassphraseOpts
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: GenPassphraseOpts -> GenPassphraseOpts -> Bool
== :: GenPassphraseOpts -> GenPassphraseOpts -> Bool
$c/= :: GenPassphraseOpts -> GenPassphraseOpts -> Bool
/= :: GenPassphraseOpts -> GenPassphraseOpts -> Bool
Eq, Int -> GenPassphraseOpts -> ShowS
[GenPassphraseOpts] -> ShowS
GenPassphraseOpts -> String
(Int -> GenPassphraseOpts -> ShowS)
-> (GenPassphraseOpts -> String)
-> ([GenPassphraseOpts] -> ShowS)
-> Show GenPassphraseOpts
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> GenPassphraseOpts -> ShowS
showsPrec :: Int -> GenPassphraseOpts -> ShowS
$cshow :: GenPassphraseOpts -> String
show :: GenPassphraseOpts -> String
$cshowList :: [GenPassphraseOpts] -> ShowS
showList :: [GenPassphraseOpts] -> ShowS
Show)

-- | A language indicating the dictionary that generated a trigraph
data Language
  = English
  | Spanish
  | CustomTrigraph TrigraphConfig
  deriving stock (Language -> Language -> Bool
(Language -> Language -> Bool)
-> (Language -> Language -> Bool) -> Eq Language
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Language -> Language -> Bool
== :: Language -> Language -> Bool
$c/= :: Language -> Language -> Bool
/= :: Language -> Language -> Bool
Eq, Int -> Language -> ShowS
[Language] -> ShowS
Language -> String
(Int -> Language -> ShowS)
-> (Language -> String) -> ([Language] -> ShowS) -> Show Language
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Language -> ShowS
showsPrec :: Int -> Language -> ShowS
$cshow :: Language -> String
show :: Language -> String
$cshowList :: [Language] -> ShowS
showList :: [Language] -> ShowS
Show)

-- | A path to a trigraph json config file
newtype TrigraphConfig = TrigraphConfig
  {TrigraphConfig -> String
unTrigraphConfig :: FilePath}
  deriving stock (TrigraphConfig -> TrigraphConfig -> Bool
(TrigraphConfig -> TrigraphConfig -> Bool)
-> (TrigraphConfig -> TrigraphConfig -> Bool) -> Eq TrigraphConfig
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TrigraphConfig -> TrigraphConfig -> Bool
== :: TrigraphConfig -> TrigraphConfig -> Bool
$c/= :: TrigraphConfig -> TrigraphConfig -> Bool
/= :: TrigraphConfig -> TrigraphConfig -> Bool
Eq, Int -> TrigraphConfig -> ShowS
[TrigraphConfig] -> ShowS
TrigraphConfig -> String
(Int -> TrigraphConfig -> ShowS)
-> (TrigraphConfig -> String)
-> ([TrigraphConfig] -> ShowS)
-> Show TrigraphConfig
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TrigraphConfig -> ShowS
showsPrec :: Int -> TrigraphConfig -> ShowS
$cshow :: TrigraphConfig -> String
show :: TrigraphConfig -> String
$cshowList :: [TrigraphConfig] -> ShowS
showList :: [TrigraphConfig] -> ShowS
Show)

-- | A unigram is a single letter
newtype Unigram = Unigram {Unigram -> Char
unUnigram :: Char}
  deriving stock (Unigram -> Unigram -> Bool
(Unigram -> Unigram -> Bool)
-> (Unigram -> Unigram -> Bool) -> Eq Unigram
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Unigram -> Unigram -> Bool
== :: Unigram -> Unigram -> Bool
$c/= :: Unigram -> Unigram -> Bool
/= :: Unigram -> Unigram -> Bool
Eq, Eq Unigram
Eq Unigram =>
(Unigram -> Unigram -> Ordering)
-> (Unigram -> Unigram -> Bool)
-> (Unigram -> Unigram -> Bool)
-> (Unigram -> Unigram -> Bool)
-> (Unigram -> Unigram -> Bool)
-> (Unigram -> Unigram -> Unigram)
-> (Unigram -> Unigram -> Unigram)
-> Ord Unigram
Unigram -> Unigram -> Bool
Unigram -> Unigram -> Ordering
Unigram -> Unigram -> Unigram
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
$ccompare :: Unigram -> Unigram -> Ordering
compare :: Unigram -> Unigram -> Ordering
$c< :: Unigram -> Unigram -> Bool
< :: Unigram -> Unigram -> Bool
$c<= :: Unigram -> Unigram -> Bool
<= :: Unigram -> Unigram -> Bool
$c> :: Unigram -> Unigram -> Bool
> :: Unigram -> Unigram -> Bool
$c>= :: Unigram -> Unigram -> Bool
>= :: Unigram -> Unigram -> Bool
$cmax :: Unigram -> Unigram -> Unigram
max :: Unigram -> Unigram -> Unigram
$cmin :: Unigram -> Unigram -> Unigram
min :: Unigram -> Unigram -> Unigram
Ord, Int -> Unigram -> ShowS
[Unigram] -> ShowS
Unigram -> String
(Int -> Unigram -> ShowS)
-> (Unigram -> String) -> ([Unigram] -> ShowS) -> Show Unigram
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Unigram -> ShowS
showsPrec :: Int -> Unigram -> ShowS
$cshow :: Unigram -> String
show :: Unigram -> String
$cshowList :: [Unigram] -> ShowS
showList :: [Unigram] -> ShowS
Show)
  deriving newtype (Maybe Unigram
Value -> Parser [Unigram]
Value -> Parser Unigram
(Value -> Parser Unigram)
-> (Value -> Parser [Unigram]) -> Maybe Unigram -> FromJSON Unigram
forall a.
(Value -> Parser a)
-> (Value -> Parser [a]) -> Maybe a -> FromJSON a
$cparseJSON :: Value -> Parser Unigram
parseJSON :: Value -> Parser Unigram
$cparseJSONList :: Value -> Parser [Unigram]
parseJSONList :: Value -> Parser [Unigram]
$comittedField :: Maybe Unigram
omittedField :: Maybe Unigram
FromJSON, FromJSONKeyFunction [Unigram]
FromJSONKeyFunction Unigram
FromJSONKeyFunction Unigram
-> FromJSONKeyFunction [Unigram] -> FromJSONKey Unigram
forall a.
FromJSONKeyFunction a -> FromJSONKeyFunction [a] -> FromJSONKey a
$cfromJSONKey :: FromJSONKeyFunction Unigram
fromJSONKey :: FromJSONKeyFunction Unigram
$cfromJSONKeyList :: FromJSONKeyFunction [Unigram]
fromJSONKeyList :: FromJSONKeyFunction [Unigram]
FromJSONKey, Unigram -> ()
(Unigram -> ()) -> NFData Unigram
forall a. (a -> ()) -> NFData a
$crnf :: Unigram -> ()
rnf :: Unigram -> ()
NFData, [Unigram] -> Value
[Unigram] -> Encoding
Unigram -> Bool
Unigram -> Value
Unigram -> Encoding
(Unigram -> Value)
-> (Unigram -> Encoding)
-> ([Unigram] -> Value)
-> ([Unigram] -> Encoding)
-> (Unigram -> Bool)
-> ToJSON Unigram
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> (a -> Bool)
-> ToJSON a
$ctoJSON :: Unigram -> Value
toJSON :: Unigram -> Value
$ctoEncoding :: Unigram -> Encoding
toEncoding :: Unigram -> Encoding
$ctoJSONList :: [Unigram] -> Value
toJSONList :: [Unigram] -> Value
$ctoEncodingList :: [Unigram] -> Encoding
toEncodingList :: [Unigram] -> Encoding
$comitField :: Unigram -> Bool
omitField :: Unigram -> Bool
ToJSON, ToJSONKeyFunction [Unigram]
ToJSONKeyFunction Unigram
ToJSONKeyFunction Unigram
-> ToJSONKeyFunction [Unigram] -> ToJSONKey Unigram
forall a.
ToJSONKeyFunction a -> ToJSONKeyFunction [a] -> ToJSONKey a
$ctoJSONKey :: ToJSONKeyFunction Unigram
toJSONKey :: ToJSONKeyFunction Unigram
$ctoJSONKeyList :: ToJSONKeyFunction [Unigram]
toJSONKeyList :: ToJSONKeyFunction [Unigram]
ToJSONKey)

-- | A digram is a sequence of two letters
data Digram = Digram Char Char
  deriving stock (Digram -> Digram -> Bool
(Digram -> Digram -> Bool)
-> (Digram -> Digram -> Bool) -> Eq Digram
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Digram -> Digram -> Bool
== :: Digram -> Digram -> Bool
$c/= :: Digram -> Digram -> Bool
/= :: Digram -> Digram -> Bool
Eq, (forall x. Digram -> Rep Digram x)
-> (forall x. Rep Digram x -> Digram) -> Generic Digram
forall x. Rep Digram x -> Digram
forall x. Digram -> Rep Digram x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Digram -> Rep Digram x
from :: forall x. Digram -> Rep Digram x
$cto :: forall x. Rep Digram x -> Digram
to :: forall x. Rep Digram x -> Digram
Generic, Int -> Digram -> ShowS
[Digram] -> ShowS
Digram -> String
(Int -> Digram -> ShowS)
-> (Digram -> String) -> ([Digram] -> ShowS) -> Show Digram
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Digram -> ShowS
showsPrec :: Int -> Digram -> ShowS
$cshow :: Digram -> String
show :: Digram -> String
$cshowList :: [Digram] -> ShowS
showList :: [Digram] -> ShowS
Show)
  deriving anyclass (Digram -> ()
(Digram -> ()) -> NFData Digram
forall a. (a -> ()) -> NFData a
$crnf :: Digram -> ()
rnf :: Digram -> ()
NFData)

-- | A trigrams is a sequence of three letters
data Trigram = Trigram Char Char Char
  deriving stock (Trigram -> Trigram -> Bool
(Trigram -> Trigram -> Bool)
-> (Trigram -> Trigram -> Bool) -> Eq Trigram
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Trigram -> Trigram -> Bool
== :: Trigram -> Trigram -> Bool
$c/= :: Trigram -> Trigram -> Bool
/= :: Trigram -> Trigram -> Bool
Eq, (forall x. Trigram -> Rep Trigram x)
-> (forall x. Rep Trigram x -> Trigram) -> Generic Trigram
forall x. Rep Trigram x -> Trigram
forall x. Trigram -> Rep Trigram x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Trigram -> Rep Trigram x
from :: forall x. Trigram -> Rep Trigram x
$cto :: forall x. Rep Trigram x -> Trigram
to :: forall x. Rep Trigram x -> Trigram
Generic, Int -> Trigram -> ShowS
[Trigram] -> ShowS
Trigram -> String
(Int -> Trigram -> ShowS)
-> (Trigram -> String) -> ([Trigram] -> ShowS) -> Show Trigram
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Trigram -> ShowS
showsPrec :: Int -> Trigram -> ShowS
$cshow :: Trigram -> String
show :: Trigram -> String
$cshowList :: [Trigram] -> ShowS
showList :: [Trigram] -> ShowS
Show)
  deriving anyclass (Trigram -> ()
(Trigram -> ()) -> NFData Trigram
forall a. (a -> ()) -> NFData a
$crnf :: Trigram -> ()
rnf :: Trigram -> ()
NFData)

-- | A frequency represents the number of times a given trigram occurs
--   in a language
newtype Frequency = Frequency {Frequency -> Int
unFrequency :: Int}
  deriving stock (Frequency -> Frequency -> Bool
(Frequency -> Frequency -> Bool)
-> (Frequency -> Frequency -> Bool) -> Eq Frequency
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Frequency -> Frequency -> Bool
== :: Frequency -> Frequency -> Bool
$c/= :: Frequency -> Frequency -> Bool
/= :: Frequency -> Frequency -> Bool
Eq, Int -> Frequency -> ShowS
[Frequency] -> ShowS
Frequency -> String
(Int -> Frequency -> ShowS)
-> (Frequency -> String)
-> ([Frequency] -> ShowS)
-> Show Frequency
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Frequency -> ShowS
showsPrec :: Int -> Frequency -> ShowS
$cshow :: Frequency -> String
show :: Frequency -> String
$cshowList :: [Frequency] -> ShowS
showList :: [Frequency] -> ShowS
Show)
  deriving newtype (Maybe Frequency
Value -> Parser [Frequency]
Value -> Parser Frequency
(Value -> Parser Frequency)
-> (Value -> Parser [Frequency])
-> Maybe Frequency
-> FromJSON Frequency
forall a.
(Value -> Parser a)
-> (Value -> Parser [a]) -> Maybe a -> FromJSON a
$cparseJSON :: Value -> Parser Frequency
parseJSON :: Value -> Parser Frequency
$cparseJSONList :: Value -> Parser [Frequency]
parseJSONList :: Value -> Parser [Frequency]
$comittedField :: Maybe Frequency
omittedField :: Maybe Frequency
FromJSON, [Frequency] -> Value
[Frequency] -> Encoding
Frequency -> Bool
Frequency -> Value
Frequency -> Encoding
(Frequency -> Value)
-> (Frequency -> Encoding)
-> ([Frequency] -> Value)
-> ([Frequency] -> Encoding)
-> (Frequency -> Bool)
-> ToJSON Frequency
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> (a -> Bool)
-> ToJSON a
$ctoJSON :: Frequency -> Value
toJSON :: Frequency -> Value
$ctoEncoding :: Frequency -> Encoding
toEncoding :: Frequency -> Encoding
$ctoJSONList :: [Frequency] -> Value
toJSONList :: [Frequency] -> Value
$ctoEncodingList :: [Frequency] -> Encoding
toEncodingList :: [Frequency] -> Encoding
$comitField :: Frequency -> Bool
omitField :: Frequency -> Bool
ToJSON, Frequency -> ()
(Frequency -> ()) -> NFData Frequency
forall a. (a -> ()) -> NFData a
$crnf :: Frequency -> ()
rnf :: Frequency -> ()
NFData, Int -> Frequency
Frequency -> Int
Frequency -> [Frequency]
Frequency -> Frequency
Frequency -> Frequency -> [Frequency]
Frequency -> Frequency -> Frequency -> [Frequency]
(Frequency -> Frequency)
-> (Frequency -> Frequency)
-> (Int -> Frequency)
-> (Frequency -> Int)
-> (Frequency -> [Frequency])
-> (Frequency -> Frequency -> [Frequency])
-> (Frequency -> Frequency -> [Frequency])
-> (Frequency -> Frequency -> Frequency -> [Frequency])
-> Enum Frequency
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: Frequency -> Frequency
succ :: Frequency -> Frequency
$cpred :: Frequency -> Frequency
pred :: Frequency -> Frequency
$ctoEnum :: Int -> Frequency
toEnum :: Int -> Frequency
$cfromEnum :: Frequency -> Int
fromEnum :: Frequency -> Int
$cenumFrom :: Frequency -> [Frequency]
enumFrom :: Frequency -> [Frequency]
$cenumFromThen :: Frequency -> Frequency -> [Frequency]
enumFromThen :: Frequency -> Frequency -> [Frequency]
$cenumFromTo :: Frequency -> Frequency -> [Frequency]
enumFromTo :: Frequency -> Frequency -> [Frequency]
$cenumFromThenTo :: Frequency -> Frequency -> Frequency -> [Frequency]
enumFromThenTo :: Frequency -> Frequency -> Frequency -> [Frequency]
Enum, Enum Frequency
Real Frequency
(Real Frequency, Enum Frequency) =>
(Frequency -> Frequency -> Frequency)
-> (Frequency -> Frequency -> Frequency)
-> (Frequency -> Frequency -> Frequency)
-> (Frequency -> Frequency -> Frequency)
-> (Frequency -> Frequency -> (Frequency, Frequency))
-> (Frequency -> Frequency -> (Frequency, Frequency))
-> (Frequency -> Integer)
-> Integral Frequency
Frequency -> Integer
Frequency -> Frequency -> (Frequency, Frequency)
Frequency -> Frequency -> Frequency
forall a.
(Real a, Enum a) =>
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
$cquot :: Frequency -> Frequency -> Frequency
quot :: Frequency -> Frequency -> Frequency
$crem :: Frequency -> Frequency -> Frequency
rem :: Frequency -> Frequency -> Frequency
$cdiv :: Frequency -> Frequency -> Frequency
div :: Frequency -> Frequency -> Frequency
$cmod :: Frequency -> Frequency -> Frequency
mod :: Frequency -> Frequency -> Frequency
$cquotRem :: Frequency -> Frequency -> (Frequency, Frequency)
quotRem :: Frequency -> Frequency -> (Frequency, Frequency)
$cdivMod :: Frequency -> Frequency -> (Frequency, Frequency)
divMod :: Frequency -> Frequency -> (Frequency, Frequency)
$ctoInteger :: Frequency -> Integer
toInteger :: Frequency -> Integer
Integral, Integer -> Frequency
Frequency -> Frequency
Frequency -> Frequency -> Frequency
(Frequency -> Frequency -> Frequency)
-> (Frequency -> Frequency -> Frequency)
-> (Frequency -> Frequency -> Frequency)
-> (Frequency -> Frequency)
-> (Frequency -> Frequency)
-> (Frequency -> Frequency)
-> (Integer -> Frequency)
-> Num Frequency
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: Frequency -> Frequency -> Frequency
+ :: Frequency -> Frequency -> Frequency
$c- :: Frequency -> Frequency -> Frequency
- :: Frequency -> Frequency -> Frequency
$c* :: Frequency -> Frequency -> Frequency
* :: Frequency -> Frequency -> Frequency
$cnegate :: Frequency -> Frequency
negate :: Frequency -> Frequency
$cabs :: Frequency -> Frequency
abs :: Frequency -> Frequency
$csignum :: Frequency -> Frequency
signum :: Frequency -> Frequency
$cfromInteger :: Integer -> Frequency
fromInteger :: Integer -> Frequency
Num, Eq Frequency
Eq Frequency =>
(Frequency -> Frequency -> Ordering)
-> (Frequency -> Frequency -> Bool)
-> (Frequency -> Frequency -> Bool)
-> (Frequency -> Frequency -> Bool)
-> (Frequency -> Frequency -> Bool)
-> (Frequency -> Frequency -> Frequency)
-> (Frequency -> Frequency -> Frequency)
-> Ord Frequency
Frequency -> Frequency -> Bool
Frequency -> Frequency -> Ordering
Frequency -> Frequency -> Frequency
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
$ccompare :: Frequency -> Frequency -> Ordering
compare :: Frequency -> Frequency -> Ordering
$c< :: Frequency -> Frequency -> Bool
< :: Frequency -> Frequency -> Bool
$c<= :: Frequency -> Frequency -> Bool
<= :: Frequency -> Frequency -> Bool
$c> :: Frequency -> Frequency -> Bool
> :: Frequency -> Frequency -> Bool
$c>= :: Frequency -> Frequency -> Bool
>= :: Frequency -> Frequency -> Bool
$cmax :: Frequency -> Frequency -> Frequency
max :: Frequency -> Frequency -> Frequency
$cmin :: Frequency -> Frequency -> Frequency
min :: Frequency -> Frequency -> Frequency
Ord, Num Frequency
Ord Frequency
(Num Frequency, Ord Frequency) =>
(Frequency -> Rational) -> Real Frequency
Frequency -> Rational
forall a. (Num a, Ord a) => (a -> Rational) -> Real a
$ctoRational :: Frequency -> Rational
toRational :: Frequency -> Rational
Real)

-- | Frequencies maps a unigram to a frequency
newtype Frequencies = Frequencies {Frequencies -> Map Unigram Frequency
unFrequencies :: Map Unigram Frequency}
  deriving stock (Frequencies -> Frequencies -> Bool
(Frequencies -> Frequencies -> Bool)
-> (Frequencies -> Frequencies -> Bool) -> Eq Frequencies
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Frequencies -> Frequencies -> Bool
== :: Frequencies -> Frequencies -> Bool
$c/= :: Frequencies -> Frequencies -> Bool
/= :: Frequencies -> Frequencies -> Bool
Eq, Int -> Frequencies -> ShowS
[Frequencies] -> ShowS
Frequencies -> String
(Int -> Frequencies -> ShowS)
-> (Frequencies -> String)
-> ([Frequencies] -> ShowS)
-> Show Frequencies
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Frequencies -> ShowS
showsPrec :: Int -> Frequencies -> ShowS
$cshow :: Frequencies -> String
show :: Frequencies -> String
$cshowList :: [Frequencies] -> ShowS
showList :: [Frequencies] -> ShowS
Show)
  deriving newtype (Maybe Frequencies
Value -> Parser [Frequencies]
Value -> Parser Frequencies
(Value -> Parser Frequencies)
-> (Value -> Parser [Frequencies])
-> Maybe Frequencies
-> FromJSON Frequencies
forall a.
(Value -> Parser a)
-> (Value -> Parser [a]) -> Maybe a -> FromJSON a
$cparseJSON :: Value -> Parser Frequencies
parseJSON :: Value -> Parser Frequencies
$cparseJSONList :: Value -> Parser [Frequencies]
parseJSONList :: Value -> Parser [Frequencies]
$comittedField :: Maybe Frequencies
omittedField :: Maybe Frequencies
FromJSON, [Frequencies] -> Value
[Frequencies] -> Encoding
Frequencies -> Bool
Frequencies -> Value
Frequencies -> Encoding
(Frequencies -> Value)
-> (Frequencies -> Encoding)
-> ([Frequencies] -> Value)
-> ([Frequencies] -> Encoding)
-> (Frequencies -> Bool)
-> ToJSON Frequencies
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> (a -> Bool)
-> ToJSON a
$ctoJSON :: Frequencies -> Value
toJSON :: Frequencies -> Value
$ctoEncoding :: Frequencies -> Encoding
toEncoding :: Frequencies -> Encoding
$ctoJSONList :: [Frequencies] -> Value
toJSONList :: [Frequencies] -> Value
$ctoEncodingList :: [Frequencies] -> Encoding
toEncodingList :: [Frequencies] -> Encoding
$comitField :: Frequencies -> Bool
omitField :: Frequencies -> Bool
ToJSON, Frequencies -> ()
(Frequencies -> ()) -> NFData Frequencies
forall a. (a -> ()) -> NFData a
$crnf :: Frequencies -> ()
rnf :: Frequencies -> ()
NFData)

-- | A trigraph is a mapping of all digrams to frequencies. That is, for a set of
--   digrams, it contains the frequencies of all possible trigram candidates.
newtype Trigraph = Trigraph {Trigraph -> Map Digram Frequencies
unTrigraph :: Map Digram Frequencies}
  deriving stock (Trigraph -> Trigraph -> Bool
(Trigraph -> Trigraph -> Bool)
-> (Trigraph -> Trigraph -> Bool) -> Eq Trigraph
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Trigraph -> Trigraph -> Bool
== :: Trigraph -> Trigraph -> Bool
$c/= :: Trigraph -> Trigraph -> Bool
/= :: Trigraph -> Trigraph -> Bool
Eq, Int -> Trigraph -> ShowS
[Trigraph] -> ShowS
Trigraph -> String
(Int -> Trigraph -> ShowS)
-> (Trigraph -> String) -> ([Trigraph] -> ShowS) -> Show Trigraph
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Trigraph -> ShowS
showsPrec :: Int -> Trigraph -> ShowS
$cshow :: Trigraph -> String
show :: Trigraph -> String
$cshowList :: [Trigraph] -> ShowS
showList :: [Trigraph] -> ShowS
Show)
  deriving newtype (Maybe Trigraph
Value -> Parser [Trigraph]
Value -> Parser Trigraph
(Value -> Parser Trigraph)
-> (Value -> Parser [Trigraph])
-> Maybe Trigraph
-> FromJSON Trigraph
forall a.
(Value -> Parser a)
-> (Value -> Parser [a]) -> Maybe a -> FromJSON a
$cparseJSON :: Value -> Parser Trigraph
parseJSON :: Value -> Parser Trigraph
$cparseJSONList :: Value -> Parser [Trigraph]
parseJSONList :: Value -> Parser [Trigraph]
$comittedField :: Maybe Trigraph
omittedField :: Maybe Trigraph
FromJSON, [Trigraph] -> Value
[Trigraph] -> Encoding
Trigraph -> Bool
Trigraph -> Value
Trigraph -> Encoding
(Trigraph -> Value)
-> (Trigraph -> Encoding)
-> ([Trigraph] -> Value)
-> ([Trigraph] -> Encoding)
-> (Trigraph -> Bool)
-> ToJSON Trigraph
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> (a -> Bool)
-> ToJSON a
$ctoJSON :: Trigraph -> Value
toJSON :: Trigraph -> Value
$ctoEncoding :: Trigraph -> Encoding
toEncoding :: Trigraph -> Encoding
$ctoJSONList :: [Trigraph] -> Value
toJSONList :: [Trigraph] -> Value
$ctoEncodingList :: [Trigraph] -> Encoding
toEncodingList :: [Trigraph] -> Encoding
$comitField :: Trigraph -> Bool
omitField :: Trigraph -> Bool
ToJSON, Trigraph -> ()
(Trigraph -> ()) -> NFData Trigraph
forall a. (a -> ()) -> NFData a
$crnf :: Trigraph -> ()
rnf :: Trigraph -> ()
NFData)

-- | A natural language word
newtype Word = Word {Word -> Text
unWord :: Text}
  deriving stock (Word -> Word -> Bool
(Word -> Word -> Bool) -> (Word -> Word -> Bool) -> Eq Word
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Word -> Word -> Bool
== :: Word -> Word -> Bool
$c/= :: Word -> Word -> Bool
/= :: Word -> Word -> Bool
Eq, Int -> Word -> ShowS
[Word] -> ShowS
Word -> String
(Int -> Word -> ShowS)
-> (Word -> String) -> ([Word] -> ShowS) -> Show Word
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Word -> ShowS
showsPrec :: Int -> Word -> ShowS
$cshow :: Word -> String
show :: Word -> String
$cshowList :: [Word] -> ShowS
showList :: [Word] -> ShowS
Show)

instance TextShow Digram where
  showb :: Digram -> Builder
showb (Digram Char
c1 Char
c2) = String -> Builder
fromString [Char
Item String
c1, Char
Item String
c2]

instance ToJSON Digram where
  toJSON :: Digram -> Value
toJSON (Digram Char
c1 Char
c2) = Text -> Value
Aeson.String [Char
Item Text
c1, Char
Item Text
c2]

instance ToJSONKey Digram where
  toJSONKey :: ToJSONKeyFunction Digram
toJSONKey = (Digram -> Text) -> ToJSONKeyFunction Digram
forall a. (a -> Text) -> ToJSONKeyFunction a
toJSONKeyText Digram -> Text
toText
    where
      toText :: Digram -> Text
      toText :: Digram -> Text
toText = Digram -> Text
forall a. TextShow a => a -> Text
showt

instance FromJSON Digram where
  parseJSON :: Value -> Parser Digram
parseJSON = String -> (Text -> Parser Digram) -> Value -> Parser Digram
forall a. String -> (Text -> Parser a) -> Value -> Parser a
Aeson.withText String
"Digram" Text -> Parser Digram
parseDigram

instance FromJSONKey Digram where
  fromJSONKey :: FromJSONKeyFunction Digram
fromJSONKey = (Text -> Parser Digram) -> FromJSONKeyFunction Digram
forall a. (Text -> Parser a) -> FromJSONKeyFunction a
FromJSONKeyTextParser Text -> Parser Digram
parseDigram

instance Ord Digram where
  (Digram Char
a1 Char
b1) compare :: Digram -> Digram -> Ordering
`compare` (Digram Char
a2 Char
b2) =
    (Char
a1, Char
b1) (Char, Char) -> (Char, Char) -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` (Char
a2, Char
b2)

instance Ord Trigram where
  (Trigram Char
a1 Char
b1 Char
c1) compare :: Trigram -> Trigram -> Ordering
`compare` (Trigram Char
a2 Char
b2 Char
c2) =
    (Char
a1, Char
b1, Char
c1) (Char, Char, Char) -> (Char, Char, Char) -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` (Char
a2, Char
b2, Char
c2)

parseDigram :: Text -> Parser Digram
parseDigram :: Text -> Parser Digram
parseDigram = ((Char -> Char -> Digram) -> (Char, Char) -> Digram
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Char -> Char -> Digram
Digram <$>) (Parser (Char, Char) -> Parser Digram)
-> (Text -> Parser (Char, Char)) -> Text -> Parser Digram
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Parser (Char, Char)
Text -> Parser (Item Text, Item Text)
forall {l} {f :: * -> *}.
(IsList l, MonadFail f) =>
l -> f (Item l, Item l)
fromText
  where
    fromText :: l -> f (Item l, Item l)
fromText [Item l
ch1, Item l
ch2] = (Item l, Item l) -> f (Item l, Item l)
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Item l
ch1, Item l
ch2)
    fromText l
_ = String -> f (Item l, Item l)
forall a. String -> f a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Not a string of length 2"