{-# OPTIONS_HADDOCK show-extensions #-}

-- |
-- Module      :  Interpreter.StringConversion
-- Copyright   :  (c) OleksandrZhabenko 2021
-- 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
import Data.Char (isDigit)
import Data.List (sort,nub,intercalate,(\\))
import Data.Monoid (mappend)

convStringInterpreter :: String -> String -> String
convStringInterpreter :: String -> String -> String
convStringInterpreter String
contrs String
xs
 | String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
contrs = String
xs
 | String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (String -> String
forall a. Eq a => [a] -> [a]
nub (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
filter (\Char
t -> Char
t Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'1' Bool -> Bool -> Bool
&& [Char
t] String -> String -> Bool
forall a. Ord a => a -> a -> Bool
<= Int -> String
forall a. Show a => a -> String
show ([String] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([String] -> Int) -> (String -> [String]) -> String -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
words (String -> Int) -> String -> Int
forall a b. (a -> b) -> a -> b
$ String
xs)) (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String
contrs) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
2 = String
xs
 | Bool
otherwise = let cntrs :: String
cntrs = String -> String
forall a. Eq a => [a] -> [a]
nub (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
filter (\Char
t -> Char
t Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'1' Bool -> Bool -> Bool
&& [Char
t] String -> String -> Bool
forall a. Ord a => a -> a -> Bool
<= Int -> String
forall a. Show a => a -> String
show ([String] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([String] -> Int) -> (String -> [String]) -> String -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
words (String -> Int) -> String -> Int
forall a b. (a -> b) -> a -> b
$ String
xs)) (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String
contrs
                   tss :: [String]
tss = String -> [String]
words String
xs in
                     case String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
cntrs of
                      Int
2 -> let pos :: Int
pos = Maybe Int -> Int
forall a. HasCallStack => Maybe a -> a
fromJust (String -> Maybe Int
forall a. Read a => String -> Maybe a
readMaybe (Int -> String -> String
forall a. Int -> [a] -> [a]
take Int
1 String
cntrs)::Maybe Int)
                               number :: Int
number = Maybe Int -> Int
forall a. HasCallStack => Maybe a -> a
fromJust (String -> Maybe Int
forall a. Read a => String -> Maybe a
readMaybe (Int -> String -> String
forall a. Int -> [a] -> [a]
drop Int
1 String
cntrs)::Maybe Int)
                               ([String]
zss,[String]
yss) = Int -> [String] -> ([String], [String])
forall a. Int -> [a] -> ([a], [a])
splitAt (Int
pos Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) [String]
tss
                               ([String]
kss,[String]
lss) = Int -> [String] -> ([String], [String])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
number [String]
yss in
                                 if [String] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [String]
tss Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
pos Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
number Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1 then String
xs
                                 else if [String] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
zss then [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
kss String -> String -> String
forall a. Monoid a => a -> a -> a
`mappend` String
" " String -> String -> String
forall a. Monoid a => a -> a -> a
`mappend` String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
" " [String]
lss
                                      else String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
" " [String]
zss String -> String -> String
forall a. Monoid a => a -> a -> a
`mappend` String
" " String -> String -> String
forall a. Monoid a => a -> a -> a
`mappend` [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
kss String -> String -> String
forall a. Monoid a => a -> a -> a
`mappend` String
" " String -> String -> String
forall a. Monoid a => a -> a -> a
`mappend` String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
" " [String]
lss
                      Int
_ -> let idxs :: [Int]
idxs = (Char -> Int) -> String -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map (\Char
x -> Maybe Int -> Int
forall a. HasCallStack => Maybe a -> a
fromJust (String -> Maybe Int
forall a. Read a => String -> Maybe a
readMaybe [Char
x]::Maybe Int)) (String -> [Int]) -> String -> [Int]
forall a b. (a -> b) -> a -> b
$ String
cntrs
                               wordsN :: [String]
wordsN = (Int -> String) -> [Int] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (\Int
i -> [String]
tss [String] -> Int -> String
forall a. [a] -> Int -> a
!! (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)) [Int]
idxs
                               restWords :: [String]
restWords = [String]
tss [String] -> [String] -> [String]
forall a. Eq a => [a] -> [a] -> [a]
\\ [String]
wordsN
                                 in String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
" " [String]
restWords String -> String -> String
forall a. Monoid a => a -> a -> a
`mappend` String
" " String -> String -> String
forall a. Monoid a => a -> a -> a
`mappend` [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
wordsN