{-# OPTIONS_HADDOCK show-extensions #-}
{-# LANGUAGE ScopedTypeVariables #-}


-- |
-- Module      :  Interpreter.StringConversion
-- Copyright   :  (c) OleksandrZhabenko 2021-2022
-- License     :  MIT
-- Stability   :  Experimental
-- Maintainer  :  olexandr543@yahoo.com
--
-- A library that has commonly used function for the phonetic-languages implementations.

module Interpreter.StringConversion where

import Text.Read (readMaybe)
import Data.Maybe (fromJust,fromMaybe)
import Data.Char (isDigit)
import Data.List (sort,(\\))
import Data.Monoid (mappend)
import Control.Exception

{-| Converts the second given string into the form that can be easily used by the phonetic-languages-simplified-* implementations. -}
convStringInterpreter :: String -> String -> String
convStringInterpreter :: String -> String -> String
convStringInterpreter String
contrs String
xs
 | forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
contrs = String
xs
 | forall (t :: * -> *) a. Foldable t => t a -> Bool
null forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
words forall a b. (a -> b) -> a -> b
$ String
xs = String
xs
 | case forall a. (a -> Bool) -> [a] -> [a]
filter (\Char
y -> Char -> Bool
isDigit Char
y Bool -> Bool -> Bool
|| Char
y forall a. Eq a => a -> a -> Bool
== Char
'/' Bool -> Bool -> Bool
|| Char
y forall a. Eq a => a -> a -> Bool
== Char
'-') String
contrs of { Char
a:Char
'/':String
bs -> Char
a forall a. Eq a => a -> a -> Bool
/= Char
'/' Bool -> Bool -> Bool
&& Char
a forall a. Eq a => a -> a -> Bool
/= Char
'0' ; Char
'1':Char
'0':Char
'/':String
cs -> Bool
True ; ~String
rrr -> Bool
False } =
     let ys :: String
ys = forall a. (a -> Bool) -> [a] -> [a]
filter (\Char
y -> Char -> Bool
isDigit Char
y Bool -> Bool -> Bool
|| Char
y forall a. Eq a => a -> a -> Bool
== Char
'/' Bool -> Bool -> Bool
|| Char
y forall a. Eq a => a -> a -> Bool
== Char
'-') String
contrs in
       case String
ys of
         ~Char
a:Char
'/':String
bs -> let wordsN :: [String]
wordsN = String -> [String]
words String
xs
                          wordN :: Int
wordN = forall a. Ord a => a -> a -> a
min (forall a. a -> Maybe a -> a
fromMaybe Int
1 (forall a. Read a => String -> Maybe a
readMaybe [Char
a]::Maybe Int)) (forall (t :: * -> *) a. Foldable t => t a -> Int
length [String]
wordsN)
                          pos :: Int
pos = forall a. a -> Maybe a -> a
fromMaybe Int
0 (forall a. Read a => String -> Maybe a
readMaybe String
bs::Maybe Int)
                          wrdP :: String
wrdP = [String]
wordsN forall a. [a] -> Int -> a
!! (Int
wordN forall a. Num a => a -> a -> a
- Int
1)
                          (String
ts,String
us) | Int
pos forall a. Ord a => a -> a -> Bool
>= Int
0 = forall a. Int -> [a] -> ([a], [a])
splitAt Int
pos String
wrdP
                                  | Bool
otherwise = forall a. Int -> [a] -> ([a], [a])
splitAt (forall (t :: * -> *) a. Foldable t => t a -> Int
length String
wrdP forall a. Num a => a -> a -> a
+ Int
pos) String
wrdP
                          twoWords :: String
twoWords = String
ts forall a. Monoid a => a -> a -> a
`mappend` (Char
' 'forall a. a -> [a] -> [a]
:String
us)
                          ([String]
wss,[String]
tss) = forall a. Int -> [a] -> ([a], [a])
splitAt (Int
wordN forall a. Num a => a -> a -> a
- Int
1) [String]
wordsN
                          kss :: [String]
kss = forall a. Int -> [a] -> [a]
drop Int
1 [String]
tss in
                            if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
wss then String
twoWords forall a. Monoid a => a -> a -> a
`mappend` (Char
' 'forall a. a -> [a] -> [a]
:[String] -> String
unwords [String]
kss)
                            else [String] -> String
unwords [String]
wss forall a. Monoid a => a -> a -> a
`mappend` (Char
' 'forall a. a -> [a] -> [a]
:String
twoWords) forall a. Monoid a => a -> a -> a
`mappend` (Char
' 'forall a. a -> [a] -> [a]
:[String] -> String
unwords [String]
kss)
         Char
'1':Char
'0':Char
'/':String
bs -> let wordsN :: [String]
wordsN = String -> [String]
words String
xs
                               wordN :: Int
wordN = forall a. Ord a => a -> a -> a
min Int
10 (forall (t :: * -> *) a. Foldable t => t a -> Int
length [String]
wordsN)
                               pos :: Int
pos = forall a. a -> Maybe a -> a
fromMaybe Int
0 (forall a. Read a => String -> Maybe a
readMaybe String
bs::Maybe Int)
                               wrdP :: String
wrdP = [String]
wordsN forall a. [a] -> Int -> a
!! (forall a. Ord a => a -> a -> a
min Int
9 (forall (t :: * -> *) a. Foldable t => t a -> Int
length [String]
wordsN forall a. Num a => a -> a -> a
- Int
1))
                               (String
ts,String
us) | Int
pos forall a. Ord a => a -> a -> Bool
>= Int
0 = forall a. Int -> [a] -> ([a], [a])
splitAt Int
pos String
wrdP
                                       | Bool
otherwise = forall a. Int -> [a] -> ([a], [a])
splitAt (forall (t :: * -> *) a. Foldable t => t a -> Int
length String
wrdP forall a. Num a => a -> a -> a
+ Int
pos) String
wrdP
                               twoWords :: String
twoWords = String
ts forall a. Monoid a => a -> a -> a
`mappend` (Char
' 'forall a. a -> [a] -> [a]
:String
us)
                               ([String]
wss,[String]
tss) = forall a. Int -> [a] -> ([a], [a])
splitAt Int
9 [String]
wordsN
                               kss :: [String]
kss = forall a. Int -> [a] -> [a]
drop Int
1 [String]
tss in
                               [String] -> String
unwords [String]
wss forall a. Monoid a => a -> a -> a
`mappend` (Char
' 'forall a. a -> [a] -> [a]
:String
twoWords)
 | forall (t :: * -> *) a. Foldable t => t a -> Int
length (forall a. (a -> Bool) -> [a] -> [a]
filter (\Char
t -> if (forall (t :: * -> *) a. Foldable t => t a -> Int
length forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
words forall a b. (a -> b) -> a -> b
$ String
xs) forall a. Ord a => a -> a -> Bool
>= Int
10 then Char
t forall a. Ord a => a -> a -> Bool
>= Char
'1' Bool -> Bool -> Bool
&& Char
t forall a. Ord a => a -> a -> Bool
<= Char
'9' else Char
t forall a. Ord a => a -> a -> Bool
>= Char
'1' Bool -> Bool -> Bool
&& [Char
t] forall a. Ord a => a -> a -> Bool
<= forall a. Show a => a -> String
show (forall (t :: * -> *) a. Foldable t => t a -> Int
length forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
words forall a b. (a -> b) -> a -> b
$ String
xs)) forall a b. (a -> b) -> a -> b
$ String
contrs) forall a. Ord a => a -> a -> Bool
< Int
2 = String
xs
 -- The following case is changed since the version 0.6.0.0 to support concatenations of the arbitrary two words, not needed to be consequent ones.
 | Bool
otherwise = let cntrs :: String
cntrs = (if forall a. Int -> [a] -> [a]
take Int
1 (forall a. (a -> Bool) -> [a] -> [a]
filter Char -> Bool
isDigit String
contrs) forall a. Eq a => a -> a -> Bool
== String
"0" then String
"0" else []) forall a. Monoid a => a -> a -> a
`mappend`
                     (forall a. (a -> Bool) -> [a] -> [a]
filter (\Char
t -> if (forall (t :: * -> *) a. Foldable t => t a -> Int
length forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
words forall a b. (a -> b) -> a -> b
$ String
xs) forall a. Ord a => a -> a -> Bool
>= Int
10 then Char
t forall a. Ord a => a -> a -> Bool
>= Char
'0' Bool -> Bool -> Bool
&& Char
t forall a. Ord a => a -> a -> Bool
<= Char
'9'
                                    else Char
t forall a. Ord a => a -> a -> Bool
>= Char
'1' Bool -> Bool -> Bool
&& [Char
t] forall a. Ord a => a -> a -> Bool
<= forall a. Show a => a -> String
show (forall (t :: * -> *) a. Foldable t => t a -> Int
length forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
words forall a b. (a -> b) -> a -> b
$ String
xs)) forall a b. (a -> b) -> a -> b
$ String
contrs)
                   tss :: [String]
tss = String -> [String]
words String
xs in
                     case forall (t :: * -> *) a. Foldable t => t a -> Int
length String
cntrs of
                      Int
2 -> if forall a. Int -> [a] -> [a]
take Int
1 String
cntrs forall a. Eq a => a -> a -> Bool
== String
"0" then String
xs
                           else let pos :: Int
pos = forall a. HasCallStack => Maybe a -> a
fromJust (forall a. Read a => String -> Maybe a
readMaybe (forall a. Int -> [a] -> [a]
take Int
1 String
cntrs)::Maybe Int)
                                    number :: Int
number = forall a. HasCallStack => Maybe a -> a
fromJust (forall a. Read a => String -> Maybe a
readMaybe (forall a. Int -> [a] -> [a]
drop Int
1 String
cntrs)::Maybe Int)
                                    ([String]
zss,[String]
yss) = forall a. Int -> [a] -> ([a], [a])
splitAt (Int
pos forall a. Num a => a -> a -> a
- Int
1) [String]
tss
                                    ([String]
kss,[String]
lss) = forall a. Int -> [a] -> ([a], [a])
splitAt Int
number [String]
yss in
                                     if forall (t :: * -> *) a. Foldable t => t a -> Int
length [String]
tss forall a. Ord a => a -> a -> Bool
< Int
pos forall a. Num a => a -> a -> a
+ Int
number forall a. Num a => a -> a -> a
- Int
1 then String
xs
                                     else if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
zss then forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
kss forall a. Monoid a => a -> a -> a
`mappend` String
" " forall a. Monoid a => a -> a -> a
`mappend` [String] -> String
unwords [String]
lss
                                          else [String] -> String
unwords [String]
zss forall a. Monoid a => a -> a -> a
`mappend` String
" " forall a. Monoid a => a -> a -> a
`mappend` forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
kss forall a. Monoid a => a -> a -> a
`mappend` String
" " forall a. Monoid a => a -> a -> a
`mappend` [String] -> String
unwords [String]
lss
                      Int
_ -> let idxs :: [Int]
idxs = forall a b. (a -> b) -> [a] -> [b]
map (\Char
x -> let k :: Int
k = forall a. HasCallStack => Maybe a -> a
fromJust (forall a. Read a => String -> Maybe a
readMaybe [Char
x]::Maybe Int) in if Int
k forall a. Eq a => a -> a -> Bool
== Int
0 then Int
10 else Int
k) forall a b. (a -> b) -> a -> b
$ (if forall a. Int -> [a] -> [a]
take Int
1 String
cntrs forall a. Eq a => a -> a -> Bool
== String
"0" then forall a. Int -> [a] -> [a]
drop Int
1 String
cntrs else String
cntrs)
                               wordsN :: [String]
wordsN = forall a b. (a -> b) -> [a] -> [b]
map (\Int
i -> [String]
tss forall a. [a] -> Int -> a
!! (Int
i forall a. Num a => a -> a -> a
- Int
1)) [Int]
idxs
                               restWords :: [String]
restWords = [String]
tss forall a. Eq a => [a] -> [a] -> [a]
\\ [String]
wordsN
                                 in [String] -> String
unwords [String]
restWords forall a. Monoid a => a -> a -> a
`mappend` String
" " forall a. Monoid a => a -> a -> a
`mappend` forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
wordsN

{-| Variant of the 'convStringInterpreter' with the additional possibility to correct splitting after revision. -}
convStringInterpreterIO :: String -> String -> IO String
convStringInterpreterIO :: String -> String -> IO String
convStringInterpreterIO String
contrs String
xs
 | forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
contrs = forall (m :: * -> *) a. Monad m => a -> m a
return String
xs
 | forall (t :: * -> *) a. Foldable t => t a -> Bool
null forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
words forall a b. (a -> b) -> a -> b
$ String
xs = forall (m :: * -> *) a. Monad m => a -> m a
return String
xs
 | case forall a. (a -> Bool) -> [a] -> [a]
filter (\Char
y -> Char -> Bool
isDigit Char
y Bool -> Bool -> Bool
|| Char
y forall a. Eq a => a -> a -> Bool
== Char
'/' Bool -> Bool -> Bool
|| Char
y forall a. Eq a => a -> a -> Bool
== Char
'-') String
contrs of { Char
a:Char
'/':String
bs -> Char
a forall a. Eq a => a -> a -> Bool
/= Char
'/' Bool -> Bool -> Bool
&& Char
a forall a. Eq a => a -> a -> Bool
/= Char
'0' ; Char
'1':Char
'0':Char
'/':String
cs -> Bool
True ; ~String
rrr -> Bool
False } =
     let ys :: String
ys = forall a. (a -> Bool) -> [a] -> [a]
filter (\Char
y -> Char -> Bool
isDigit Char
y Bool -> Bool -> Bool
|| Char
y forall a. Eq a => a -> a -> Bool
== Char
'/' Bool -> Bool -> Bool
|| Char
y forall a. Eq a => a -> a -> Bool
== Char
'-') String
contrs in
       case String
ys of
         ~Char
a:Char
'/':String
bs -> do
                        let wordsN :: [String]
wordsN = String -> [String]
words String
xs
                            wordN :: Int
wordN = forall a. Ord a => a -> a -> a
min (forall a. a -> Maybe a -> a
fromMaybe Int
1 (forall a. Read a => String -> Maybe a
readMaybe [Char
a]::Maybe Int)) (forall (t :: * -> *) a. Foldable t => t a -> Int
length [String]
wordsN)
                            pos :: Int
pos = forall a. a -> Maybe a -> a
fromMaybe Int
0 (forall a. Read a => String -> Maybe a
readMaybe String
bs::Maybe Int)
                            wrdP :: String
wrdP = [String]
wordsN forall a. [a] -> Int -> a
!! (Int
wordN forall a. Num a => a -> a -> a
- Int
1)
                        if forall a. Num a => a -> a
abs Int
pos forall a. Ord a => a -> a -> Bool
>= Int
8 then do
                          Int -> String -> IO Int
corr Int
pos String
wrdP forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Int
pos2 -> forall (m :: * -> *).
Monad m =>
Int -> String -> Int -> [String] -> m String
correctionF Int
pos2 String
wrdP Int
wordN [String]
wordsN
                        else forall (m :: * -> *).
Monad m =>
Int -> String -> Int -> [String] -> m String
correctionF Int
pos String
wrdP Int
wordN [String]
wordsN
         Char
'1':Char
'0':Char
'/':String
bs -> do
                        let wordsN :: [String]
wordsN = String -> [String]
words String
xs
                            wordN :: Int
wordN = forall a. Ord a => a -> a -> a
min Int
10 (forall (t :: * -> *) a. Foldable t => t a -> Int
length [String]
wordsN)
                            pos :: Int
pos = forall a. a -> Maybe a -> a
fromMaybe Int
0 (forall a. Read a => String -> Maybe a
readMaybe String
bs::Maybe Int)
                            wrdP :: String
wrdP = [String]
wordsN forall a. [a] -> Int -> a
!! (forall a. Ord a => a -> a -> a
min Int
9 (forall (t :: * -> *) a. Foldable t => t a -> Int
length [String]
wordsN forall a. Num a => a -> a -> a
- Int
1))
                        if forall a. Num a => a -> a
abs Int
pos forall a. Ord a => a -> a -> Bool
>= Int
8 then do
                          Int -> String -> IO Int
corr Int
pos String
wrdP forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Int
pos2 -> forall (m :: * -> *).
Monad m =>
Int -> String -> Int -> [String] -> m String
correctionF Int
pos2 String
wrdP Int
wordN [String]
wordsN
                        else forall (m :: * -> *).
Monad m =>
Int -> String -> Int -> [String] -> m String
correctionF Int
pos String
wrdP Int
wordN [String]
wordsN
 | forall (t :: * -> *) a. Foldable t => t a -> Int
length (forall a. (a -> Bool) -> [a] -> [a]
filter (\Char
t -> if (forall (t :: * -> *) a. Foldable t => t a -> Int
length forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
words forall a b. (a -> b) -> a -> b
$ String
xs) forall a. Ord a => a -> a -> Bool
>= Int
10 then Char
t forall a. Ord a => a -> a -> Bool
>= Char
'1' Bool -> Bool -> Bool
&& Char
t forall a. Ord a => a -> a -> Bool
<= Char
'9' else Char
t forall a. Ord a => a -> a -> Bool
>= Char
'1' Bool -> Bool -> Bool
&& [Char
t] forall a. Ord a => a -> a -> Bool
<= forall a. Show a => a -> String
show (forall (t :: * -> *) a. Foldable t => t a -> Int
length forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
words forall a b. (a -> b) -> a -> b
$ String
xs)) forall a b. (a -> b) -> a -> b
$ String
contrs) forall a. Ord a => a -> a -> Bool
< Int
2 = forall (m :: * -> *) a. Monad m => a -> m a
return String
xs
 | Bool
otherwise = let cntrs :: String
cntrs = (if forall a. Int -> [a] -> [a]
take Int
1 (forall a. (a -> Bool) -> [a] -> [a]
filter Char -> Bool
isDigit String
contrs) forall a. Eq a => a -> a -> Bool
== String
"0" then String
"0" else []) forall a. Monoid a => a -> a -> a
`mappend`
                     (forall a. (a -> Bool) -> [a] -> [a]
filter (\Char
t -> if (forall (t :: * -> *) a. Foldable t => t a -> Int
length forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
words forall a b. (a -> b) -> a -> b
$ String
xs) forall a. Ord a => a -> a -> Bool
>= Int
10 then Char
t forall a. Ord a => a -> a -> Bool
>= Char
'0' Bool -> Bool -> Bool
&& Char
t forall a. Ord a => a -> a -> Bool
<= Char
'9'
                                    else Char
t forall a. Ord a => a -> a -> Bool
>= Char
'1' Bool -> Bool -> Bool
&& [Char
t] forall a. Ord a => a -> a -> Bool
<= forall a. Show a => a -> String
show (forall (t :: * -> *) a. Foldable t => t a -> Int
length forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
words forall a b. (a -> b) -> a -> b
$ String
xs)) forall a b. (a -> b) -> a -> b
$ String
contrs)
                   tss :: [String]
tss = String -> [String]
words String
xs in
                     case forall (t :: * -> *) a. Foldable t => t a -> Int
length String
cntrs of
                      Int
2 -> if forall a. Int -> [a] -> [a]
take Int
1 String
cntrs forall a. Eq a => a -> a -> Bool
== String
"0" then forall (m :: * -> *) a. Monad m => a -> m a
return String
xs 
                           else do
                            let pos :: Int
pos = forall a. HasCallStack => Maybe a -> a
fromJust (forall a. Read a => String -> Maybe a
readMaybe (forall a. Int -> [a] -> [a]
take Int
1 String
cntrs)::Maybe Int)
                                number :: Int
number = forall a. HasCallStack => Maybe a -> a
fromJust (forall a. Read a => String -> Maybe a
readMaybe (forall a. Int -> [a] -> [a]
drop Int
1 String
cntrs)::Maybe Int)
                                ([String]
zss,[String]
yss) = forall a. Int -> [a] -> ([a], [a])
splitAt (Int
pos forall a. Num a => a -> a -> a
- Int
1) [String]
tss
                                ([String]
kss,[String]
lss) = forall a. Int -> [a] -> ([a], [a])
splitAt Int
number [String]
yss
                            if forall (t :: * -> *) a. Foldable t => t a -> Int
length [String]
tss forall a. Ord a => a -> a -> Bool
< Int
pos forall a. Num a => a -> a -> a
+ Int
number forall a. Num a => a -> a -> a
- Int
1 then forall (m :: * -> *) a. Monad m => a -> m a
return String
xs
                            else if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
zss then forall (m :: * -> *) a. Monad m => a -> m a
return (forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
kss forall a. Monoid a => a -> a -> a
`mappend` String
" " forall a. Monoid a => a -> a -> a
`mappend` [String] -> String
unwords [String]
lss)
                                 else forall (m :: * -> *) a. Monad m => a -> m a
return ([String] -> String
unwords [String]
zss forall a. Monoid a => a -> a -> a
`mappend` String
" " forall a. Monoid a => a -> a -> a
`mappend` forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
kss forall a. Monoid a => a -> a -> a
`mappend` String
" " forall a. Monoid a => a -> a -> a
`mappend` [String] -> String
unwords [String]
lss)
                      Int
_ -> let idxs :: [Int]
idxs = forall a b. (a -> b) -> [a] -> [b]
map (\Char
x -> let k :: Int
k = forall a. HasCallStack => Maybe a -> a
fromJust (forall a. Read a => String -> Maybe a
readMaybe [Char
x]::Maybe Int) in if Int
k  forall a. Eq a => a -> a -> Bool
== Int
0 then Int
10 else Int
k) forall a b. (a -> b) -> a -> b
$ (if forall a. Int -> [a] -> [a]
take Int
1 String
cntrs forall a. Eq a => a -> a -> Bool
== String
"0" then forall a. Int -> [a] -> [a]
drop Int
1 String
cntrs else String
cntrs)
                               wordsN :: [String]
wordsN = forall a b. (a -> b) -> [a] -> [b]
map (\Int
i -> [String]
tss forall a. [a] -> Int -> a
!! (Int
i forall a. Num a => a -> a -> a
- Int
1)) [Int]
idxs
                               restWords :: [String]
restWords = [String]
tss forall a. Eq a => [a] -> [a] -> [a]
\\ [String]
wordsN
                                 in forall (m :: * -> *) a. Monad m => a -> m a
return ([String] -> String
unwords [String]
restWords forall a. Monoid a => a -> a -> a
`mappend` String
" " forall a. Monoid a => a -> a -> a
`mappend` forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
wordsN)

corr :: Int -> String -> IO Int
corr :: Int -> String -> IO Int
corr Int
pos String
wrdP = do
  let (String
ts, String
us) | Int
pos forall a. Ord a => a -> a -> Bool
>= Int
0 = forall a. Int -> [a] -> ([a], [a])
splitAt Int
pos String
wrdP
               | Bool
otherwise = forall a. Int -> [a] -> ([a], [a])
splitAt (forall (t :: * -> *) a. Foldable t => t a -> Int
length String
wrdP forall a. Num a => a -> a -> a
+ Int
pos) String
wrdP
      twoWords :: String
twoWords = String
ts forall a. Monoid a => a -> a -> a
`mappend` (Char
' 'forall a. a -> [a] -> [a]
:String
us)
  String -> IO ()
putStrLn forall a b. (a -> b) -> a -> b
$ String
"?:       " forall a. Monoid a => a -> a -> a
`mappend` String
twoWords
  String
llls <- IO String
getLine
  if forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
llls then forall (m :: * -> *) a. Monad m => a -> m a
return Int
pos
  else do
    let tss :: [String]
tss = String -> [String]
words String
llls
        wrd0 :: Int
wrd0 = forall a. a -> Maybe a -> a
fromMaybe Int
1 (forall a. Read a => String -> Maybe a
readMaybe (forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Int -> [a] -> [a]
take Int
1 forall a b. (a -> b) -> a -> b
$ [String]
tss)::Maybe Int)
        posN :: Int
posN = forall a. a -> Maybe a -> a
fromMaybe Int
0 (forall a. Read a => String -> Maybe a
readMaybe (forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Int -> [a] -> [a]
drop Int
1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Int -> [a] -> [a]
take Int
2 forall a b. (a -> b) -> a -> b
$ [String]
tss)::Maybe Int)
    case Int
wrd0 of
      Int
1 -> Int -> String -> IO Int
corr (Int
pos forall a. Num a => a -> a -> a
- Int
posN) String
wrdP
      Int
2 -> Int -> String -> IO Int
corr (Int
pos forall a. Num a => a -> a -> a
+ Int
posN) String
wrdP
      Int
_ -> Int -> String -> IO Int
corr Int
pos String
wrdP

correctionF :: Monad m => Int -> String -> Int -> [String] -> m String
correctionF :: forall (m :: * -> *).
Monad m =>
Int -> String -> Int -> [String] -> m String
correctionF Int
pos String
wrdP Int
wordN [String]
wordsN = do
  let (String
ts,String
us) | Int
pos forall a. Ord a => a -> a -> Bool
>= Int
0 = forall a. Int -> [a] -> ([a], [a])
splitAt Int
pos String
wrdP
              | Bool
otherwise = forall a. Int -> [a] -> ([a], [a])
splitAt (forall (t :: * -> *) a. Foldable t => t a -> Int
length String
wrdP forall a. Num a => a -> a -> a
+ Int
pos) String
wrdP
      twoWords :: String
twoWords = String
ts forall a. Monoid a => a -> a -> a
`mappend` (Char
' 'forall a. a -> [a] -> [a]
:String
us)
      ([String]
wss,[String]
tss) = forall a. Int -> [a] -> ([a], [a])
splitAt (Int
wordN forall a. Num a => a -> a -> a
- Int
1) [String]
wordsN
      kss :: [String]
kss = forall a. Int -> [a] -> [a]
drop Int
1 [String]
tss
  if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
wss then forall (m :: * -> *) a. Monad m => a -> m a
return (String
twoWords forall a. Monoid a => a -> a -> a
`mappend` (Char
' 'forall a. a -> [a] -> [a]
:[String] -> String
unwords [String]
kss))
              else forall (m :: * -> *) a. Monad m => a -> m a
return ([String] -> String
unwords [String]
wss forall a. Monoid a => a -> a -> a
`mappend` (Char
' 'forall a. a -> [a] -> [a]
:String
twoWords) forall a. Monoid a => a -> a -> a
`mappend` (Char
' 'forall a. a -> [a] -> [a]
:[String] -> String
unwords [String]
kss))


{-| Inspired by: 'https://hackage.haskell.org/package/base-4.15.0.0/docs/src/GHC-IO.html#catch'
Reads a textual file given by its 'FilePath' and returns its contents lazily. If there is
some 'IOException' thrown or an empty file then returns just "". Raises an exception for the binary file. -}
readFileIfAny :: FilePath -> IO String
readFileIfAny :: String -> IO String
readFileIfAny String
file = forall e a. Exception e => IO a -> (e -> IO a) -> IO a
catch (String -> IO String
readFile String
file) (\(IOException
e :: IOException) -> forall (m :: * -> *) a. Monad m => a -> m a
return String
"")

-------------------------------------------------------------

argsConvertTextual :: String -> [String] -> [String]
argsConvertTextual :: String -> [String] -> [String]
argsConvertTextual String
ts [String]
tss
 | forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (forall a. Eq a => a -> a -> Bool
== String
ts) [String]
tss = [String]
tss
 | Bool
otherwise = [String]
tss forall a. Monoid a => a -> a -> a
`mappend` [String
ts]
{-# INLINE argsConvertTextual #-}

fullArgsConvertTextual
  :: (String -> Bool) -- ^ The predicate that checks whether the given argument is not a phonetic language word in the representation.
  -> String
  -> String
  -> [String]
  -> [String]
fullArgsConvertTextual :: (String -> Bool) -> String -> String -> [String] -> [String]
fullArgsConvertTextual String -> Bool
p String
textProcessment0 String
lineA [String]
args =
  String -> [String] -> [String]
argsConvertTextual String
textProcessment0 (forall a. (a -> Bool) -> [a] -> [a]
takeWhile String -> Bool
p [String]
args forall a. Monoid a => a -> a -> a
`mappend` String -> [String]
words String
lineA)
{-# INLINE fullArgsConvertTextual #-}

-------------------------------------------------------------

fullArgsConvertTextualSimple
  :: (String -> Bool) -- ^ The predicate that checks whether the given argument is not a phonetic language word in the representation.
  -> String
  -> [String]
  -> [String]
fullArgsConvertTextualSimple :: (String -> Bool) -> String -> [String] -> [String]
fullArgsConvertTextualSimple String -> Bool
p String
lineA [String]
args = forall a. (a -> Bool) -> [a] -> [a]
takeWhile String -> Bool
p [String]
args forall a. Monoid a => a -> a -> a
`mappend` String -> [String]
words String
lineA
{-# INLINE fullArgsConvertTextualSimple #-}