{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}

module Internal.Test.QuickCheck.Quid.Representations.Latin
    where

import Control.DeepSeq
    ( NFData )
import Control.Monad
    ( replicateM )
import Data.Char
    ( ord )
import Data.Data
    ( Data )
import Data.Hashable
    ( Hashable (..) )
import Data.List.NonEmpty
    ( NonEmpty (..) )
import Data.Maybe
    ( fromMaybe )
import Data.String
    ( IsString (..) )
import GHC.Generics
    ( Generic )
import Internal.Test.QuickCheck
    ( shrinkListNonEmpty )
import Internal.Test.QuickCheck.Quid
    ( Quid (..) )
import Internal.Test.QuickCheck.Quid.Representations
    ( nonEmptyListFromQuid, nonEmptyListToQuid )
import Test.QuickCheck
    ( Arbitrary (..)
    , Function
    , Gen
    , arbitraryBoundedEnum
    , shrinkMap
    , shrinkMapBy
    , sized
    )
import Text.Read
    ( Read (..), readMaybe )

import qualified Data.Foldable as F
import qualified Data.List.NonEmpty as NE

--------------------------------------------------------------------------------
-- Latin representation
--------------------------------------------------------------------------------

newtype Latin a = Latin { forall a. Latin a -> a
unLatin :: a }
    deriving stock (Latin a -> DataType
Latin a -> Constr
forall {a}. Data a => Typeable (Latin a)
forall a. Data a => Latin a -> DataType
forall a. Data a => Latin a -> Constr
forall a.
Data a =>
(forall b. Data b => b -> b) -> Latin a -> Latin a
forall a u.
Data a =>
Int -> (forall d. Data d => d -> u) -> Latin a -> u
forall a u.
Data a =>
(forall d. Data d => d -> u) -> Latin a -> [u]
forall a r r'.
Data a =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Latin a -> r
forall a r r'.
Data a =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Latin a -> r
forall a (m :: * -> *).
(Data a, Monad m) =>
(forall d. Data d => d -> m d) -> Latin a -> m (Latin a)
forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Latin a -> m (Latin a)
forall a (c :: * -> *).
Data a =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Latin a)
forall a (c :: * -> *).
Data a =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Latin a -> c (Latin a)
forall a (t :: * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (Latin a))
forall a (t :: * -> * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Latin a))
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Latin a)
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Latin a -> c (Latin a)
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (Latin a))
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Latin a -> m (Latin a)
$cgmapMo :: forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Latin a -> m (Latin a)
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Latin a -> m (Latin a)
$cgmapMp :: forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Latin a -> m (Latin a)
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Latin a -> m (Latin a)
$cgmapM :: forall a (m :: * -> *).
(Data a, Monad m) =>
(forall d. Data d => d -> m d) -> Latin a -> m (Latin a)
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Latin a -> u
$cgmapQi :: forall a u.
Data a =>
Int -> (forall d. Data d => d -> u) -> Latin a -> u
gmapQ :: forall u. (forall d. Data d => d -> u) -> Latin a -> [u]
$cgmapQ :: forall a u.
Data a =>
(forall d. Data d => d -> u) -> Latin a -> [u]
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Latin a -> r
$cgmapQr :: forall a r r'.
Data a =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Latin a -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Latin a -> r
$cgmapQl :: forall a r r'.
Data a =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Latin a -> r
gmapT :: (forall b. Data b => b -> b) -> Latin a -> Latin a
$cgmapT :: forall a.
Data a =>
(forall b. Data b => b -> b) -> Latin a -> Latin a
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Latin a))
$cdataCast2 :: forall a (t :: * -> * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Latin a))
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (Latin a))
$cdataCast1 :: forall a (t :: * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (Latin a))
dataTypeOf :: Latin a -> DataType
$cdataTypeOf :: forall a. Data a => Latin a -> DataType
toConstr :: Latin a -> Constr
$ctoConstr :: forall a. Data a => Latin a -> Constr
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Latin a)
$cgunfold :: forall a (c :: * -> *).
Data a =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Latin a)
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Latin a -> c (Latin a)
$cgfoldl :: forall a (c :: * -> *).
Data a =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Latin a -> c (Latin a)
Data, Latin a -> Latin a -> Bool
forall a. Eq a => Latin a -> Latin a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Latin a -> Latin a -> Bool
$c/= :: forall a. Eq a => Latin a -> Latin a -> Bool
== :: Latin a -> Latin a -> Bool
$c== :: forall a. Eq a => Latin a -> Latin a -> Bool
Eq, forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (Latin a) x -> Latin a
forall a x. Latin a -> Rep (Latin a) x
$cto :: forall a x. Rep (Latin a) x -> Latin a
$cfrom :: forall a x. Latin a -> Rep (Latin a) x
Generic, Latin a -> Latin a -> Bool
Latin a -> Latin a -> Ordering
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
forall {a}. Ord a => Eq (Latin a)
forall a. Ord a => Latin a -> Latin a -> Bool
forall a. Ord a => Latin a -> Latin a -> Ordering
forall a. Ord a => Latin a -> Latin a -> Latin a
min :: Latin a -> Latin a -> Latin a
$cmin :: forall a. Ord a => Latin a -> Latin a -> Latin a
max :: Latin a -> Latin a -> Latin a
$cmax :: forall a. Ord a => Latin a -> Latin a -> Latin a
>= :: Latin a -> Latin a -> Bool
$c>= :: forall a. Ord a => Latin a -> Latin a -> Bool
> :: Latin a -> Latin a -> Bool
$c> :: forall a. Ord a => Latin a -> Latin a -> Bool
<= :: Latin a -> Latin a -> Bool
$c<= :: forall a. Ord a => Latin a -> Latin a -> Bool
< :: Latin a -> Latin a -> Bool
$c< :: forall a. Ord a => Latin a -> Latin a -> Bool
compare :: Latin a -> Latin a -> Ordering
$ccompare :: forall a. Ord a => Latin a -> Latin a -> Ordering
Ord)
    deriving newtype (Int -> Latin a -> Int
Latin a -> Int
forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
forall {a}. Hashable a => Eq (Latin a)
forall a. Hashable a => Int -> Latin a -> Int
forall a. Hashable a => Latin a -> Int
hash :: Latin a -> Int
$chash :: forall a. Hashable a => Latin a -> Int
hashWithSalt :: Int -> Latin a -> Int
$chashWithSalt :: forall a. Hashable a => Int -> Latin a -> Int
Hashable, Latin a -> ()
forall a. NFData a => Latin a -> ()
forall a. (a -> ()) -> NFData a
rnf :: Latin a -> ()
$crnf :: forall a. NFData a => Latin a -> ()
NFData)
    deriving anyclass forall a b. Function a => (Latin a -> b) -> Latin a :-> b
forall a. (forall b. (a -> b) -> a :-> b) -> Function a
function :: forall b. (Latin a -> b) -> Latin a :-> b
$cfunction :: forall a b. Function a => (Latin a -> b) -> Latin a :-> b
Function

instance Read (Latin Quid) where
    readPrec :: ReadPrec (Latin Quid)
readPrec = forall a. IsString a => String -> a
fromString forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Read a => ReadPrec a
readPrec

instance Show (Latin Quid) where
    show :: Latin Quid -> String
show = forall a. Show a => a -> String
show forall b c a. (b -> c) -> (a -> b) -> a -> c
. Quid -> LatinString
latinStringFromQuid forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Latin a -> a
unLatin

instance IsString (Latin Quid) where
    fromString :: String -> Latin Quid
fromString = forall a. a -> Latin a
Latin forall b c a. (b -> c) -> (a -> b) -> a -> c
. LatinString -> Quid
latinStringToQuid forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. IsString a => String -> a
fromString

--------------------------------------------------------------------------------
-- Latin characters
--------------------------------------------------------------------------------

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

instance Arbitrary LatinChar where
    arbitrary :: Gen LatinChar
arbitrary = Gen LatinChar
arbitraryLatinChar
    shrink :: LatinChar -> [LatinChar]
shrink = LatinChar -> [LatinChar]
shrinkLatinChar

--------------------------------------------------------------------------------
-- Generation and shrinking of arbitrary Latin characters
--------------------------------------------------------------------------------

arbitraryLatinChar :: Gen LatinChar
arbitraryLatinChar :: Gen LatinChar
arbitraryLatinChar = forall a. (Bounded a, Enum a) => Gen a
arbitraryBoundedEnum

shrinkLatinChar :: LatinChar -> [LatinChar]
shrinkLatinChar :: LatinChar -> [LatinChar]
shrinkLatinChar = forall a b. Arbitrary a => (a -> b) -> (b -> a) -> b -> [b]
shrinkMap forall a. Enum a => Int -> a
toEnum forall a. Enum a => a -> Int
fromEnum

--------------------------------------------------------------------------------
-- Conversion between Latin characters and ordinary characters
--------------------------------------------------------------------------------

charToLatinChar :: Char -> Maybe LatinChar
charToLatinChar :: Char -> Maybe LatinChar
charToLatinChar Char
c = forall a. Read a => String -> Maybe a
readMaybe [Char
c]

latinCharToChar :: LatinChar -> Char
latinCharToChar :: LatinChar -> Char
latinCharToChar = forall a. Enum a => Int -> a
toEnum forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. Num a => a -> a -> a
+ Char -> Int
ord Char
'A') forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Enum a => a -> Int
fromEnum

--------------------------------------------------------------------------------
-- Latin strings
--------------------------------------------------------------------------------

newtype LatinString = LatinString
    { LatinString -> NonEmpty LatinChar
unLatinString :: NonEmpty LatinChar }
    deriving stock (LatinString -> LatinString -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LatinString -> LatinString -> Bool
$c/= :: LatinString -> LatinString -> Bool
== :: LatinString -> LatinString -> Bool
$c== :: LatinString -> LatinString -> Bool
Eq, Eq LatinString
LatinString -> LatinString -> Bool
LatinString -> LatinString -> Ordering
LatinString -> LatinString -> LatinString
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 :: LatinString -> LatinString -> LatinString
$cmin :: LatinString -> LatinString -> LatinString
max :: LatinString -> LatinString -> LatinString
$cmax :: LatinString -> LatinString -> LatinString
>= :: LatinString -> LatinString -> Bool
$c>= :: LatinString -> LatinString -> Bool
> :: LatinString -> LatinString -> Bool
$c> :: LatinString -> LatinString -> Bool
<= :: LatinString -> LatinString -> Bool
$c<= :: LatinString -> LatinString -> Bool
< :: LatinString -> LatinString -> Bool
$c< :: LatinString -> LatinString -> Bool
compare :: LatinString -> LatinString -> Ordering
$ccompare :: LatinString -> LatinString -> Ordering
Ord)
    deriving newtype NonEmpty LatinString -> LatinString
LatinString -> LatinString -> LatinString
forall b. Integral b => b -> LatinString -> LatinString
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
stimes :: forall b. Integral b => b -> LatinString -> LatinString
$cstimes :: forall b. Integral b => b -> LatinString -> LatinString
sconcat :: NonEmpty LatinString -> LatinString
$csconcat :: NonEmpty LatinString -> LatinString
<> :: LatinString -> LatinString -> LatinString
$c<> :: LatinString -> LatinString -> LatinString
Semigroup

instance Arbitrary LatinString where
    arbitrary :: Gen LatinString
arbitrary = Gen LatinString
arbitraryLatinString
    shrink :: LatinString -> [LatinString]
shrink = LatinString -> [LatinString]
shrinkLatinString

--------------------------------------------------------------------------------
-- Conversion between Latin strings and ordinary strings
--------------------------------------------------------------------------------

instance Read LatinString where
    readPrec :: ReadPrec LatinString
readPrec = forall a. IsString a => String -> a
fromString forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Read a => ReadPrec a
readPrec

instance Show LatinString where
    show :: LatinString -> String
show = forall a. Show a => a -> String
show forall b c a. (b -> c) -> (a -> b) -> a -> c
. LatinString -> String
latinStringToString

instance IsString LatinString where
    fromString :: String -> LatinString
fromString = String -> LatinString
unsafeStringtoLatinString

latinStringToString :: LatinString -> String
latinStringToString :: LatinString -> String
latinStringToString (LatinString NonEmpty LatinChar
cs) = forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
F.foldMap forall a. Show a => a -> String
show NonEmpty LatinChar
cs

stringToLatinString :: String -> Maybe LatinString
stringToLatinString :: String -> Maybe LatinString
stringToLatinString String
s =
    NonEmpty LatinChar -> LatinString
LatinString forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall a. [a] -> Maybe (NonEmpty a)
NE.nonEmpty forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse Char -> Maybe LatinChar
charToLatinChar String
s)

unsafeStringtoLatinString :: String -> LatinString
unsafeStringtoLatinString :: String -> LatinString
unsafeStringtoLatinString = forall a. a -> Maybe a -> a
fromMaybe forall {a}. a
raiseError forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Maybe LatinString
stringToLatinString
  where
    raiseError :: a
raiseError = forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ [String] -> String
unwords
        [ String
"A Latin quid string must be composed of one or more uppercase"
        , String
"characters in the range [A-Z]."
        ]

--------------------------------------------------------------------------------
-- Generation and shrinking of arbitrary Latin strings
--------------------------------------------------------------------------------

arbitraryLatinString :: Gen LatinString
arbitraryLatinString :: Gen LatinString
arbitraryLatinString = forall a. (Int -> Gen a) -> Gen a
sized forall a b. (a -> b) -> a -> b
$ \Int
size ->
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap NonEmpty LatinChar -> LatinString
LatinString forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a] -> NonEmpty a
(:|)
        forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen LatinChar
arbitraryLatinChar
        forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
size Gen LatinChar
arbitraryLatinChar

shrinkLatinString :: LatinString -> [LatinString]
shrinkLatinString :: LatinString -> [LatinString]
shrinkLatinString =
    forall a b. (a -> b) -> (b -> a) -> (a -> [a]) -> b -> [b]
shrinkMapBy NonEmpty LatinChar -> LatinString
LatinString LatinString -> NonEmpty LatinChar
unLatinString forall a b. (a -> b) -> a -> b
$ forall a. (a -> [a]) -> NonEmpty a -> [NonEmpty a]
shrinkListNonEmpty LatinChar -> [LatinChar]
shrinkLatinChar

--------------------------------------------------------------------------------
-- Conversion between Latin strings and quids
--------------------------------------------------------------------------------

latinStringToQuid :: LatinString -> Quid
latinStringToQuid :: LatinString -> Quid
latinStringToQuid = forall a. (Bounded a, Enum a) => NonEmpty a -> Quid
nonEmptyListToQuid forall b c a. (b -> c) -> (a -> b) -> a -> c
. LatinString -> NonEmpty LatinChar
unLatinString

latinStringFromQuid :: Quid -> LatinString
latinStringFromQuid :: Quid -> LatinString
latinStringFromQuid = NonEmpty LatinChar -> LatinString
LatinString forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (Bounded a, Enum a) => Quid -> NonEmpty a
nonEmptyListFromQuid