gibberish-3.0.0.0: src/Data/Gibberish/Utils.hs
module Data.Gibberish.Utils
( numeralConversions,
symbolConversions,
update1,
updateR,
findIndices,
textTraverse,
toQwertyKey,
qwertyKeys,
) where
import Control.Monad.Random (MonadRandom (), fromList)
import Data.Map (Map ())
import Data.Map qualified as Map
import Data.Ratio (denominator, numerator)
import Data.Text (Text ())
import Data.Text qualified as Text
-- | A mapping from letters to numbers that look like them
numeralConversions :: Map Char [Char]
numeralConversions =
Map.fromList
[ ('o', ['0']),
('l', ['1']),
('z', ['2']),
('e', ['3']),
('a', ['4']),
('s', ['5']),
('g', ['6', '9']),
('t', ['7']),
('b', ['8'])
]
-- | A mapping from letters to symbols that look like them
symbolConversions :: Map Char [Char]
symbolConversions =
Map.fromList
[ ('a', ['@']),
('l', ['!']),
('s', ['$'])
]
update1 :: Monad m => (Char -> m Char) -> Text -> Int -> m Text
update1 f t pos =
case Text.splitAt pos t of
(prefix, suffix) ->
case Text.uncons suffix of
Nothing -> pure t
Just (ch, suffix') -> do
ch' <- f ch
pure $ prefix `Text.append` (ch' `Text.cons` suffix')
updateR :: MonadRandom m => (Char -> m Char) -> Rational -> Text -> m Text
updateR f prob = textTraverse updateR'
where
updateR' ch = do
ch' <- f ch
fromList
[ (ch, toRational $ denominator prob),
(ch', toRational $ numerator prob)
]
-- | /O(n)/ The 'findIndices' function extends 'findIndex', by returning the
-- indices of all elements satisfying the predicate, in ascending order.
findIndices :: (Char -> Bool) -> Text -> [Int]
findIndices p = loop 0
where
loop !n !qs = case Text.findIndex p qs of
Just !i ->
let !j = n + i
in j : loop (j + 1) (Text.drop (i + 1) qs)
Nothing -> []
{-# INLINE [1] findIndices #-}
textTraverse :: Monad m => (Char -> m Char) -> Text -> m Text
textTraverse f = Text.foldr folder (pure Text.empty)
where
folder c accum = do
accum' <- accum
c' <- f c
pure $ Text.cons c' accum'
-- | Transform a letter-type character to something that's easy to type on a
-- QWERTY keyboard
toQwertyKey :: Char -> Char
toQwertyKey 'à' = 'a'
toQwertyKey 'á' = 'a'
toQwertyKey 'â' = 'a'
toQwertyKey 'ä' = 'a'
toQwertyKey 'å' = 'a'
toQwertyKey 'ç' = 'c'
toQwertyKey 'è' = 'e'
toQwertyKey 'é' = 'e'
toQwertyKey 'ê' = 'e'
toQwertyKey 'ë' = 'e'
toQwertyKey 'í' = 'i'
toQwertyKey 'ï' = 'i'
toQwertyKey 'ñ' = 'n'
toQwertyKey 'ó' = 'o'
toQwertyKey 'ô' = 'o'
toQwertyKey 'ö' = 'o'
toQwertyKey 'û' = 'u'
toQwertyKey 'ü' = 'u'
toQwertyKey 'ú' = 'u'
toQwertyKey c = c
-- | All the characters that are easy to type on a QWERTY keyboard
qwertyKeys :: [Char]
qwertyKeys =
"1234567890-=qwertyuiop[]\\asdfghjkl;'zxcvbnm,./!@#$%^&*()_+QWERTYUIOP{}|ASDFGHJKL:'\"ZXCVBNM<>?"