{-# LANGUAGE RankNTypes #-}
module Data.Owoify.Internal.Parser.OwoifyParser
( count
, OError(..)
, OwoifyError
, OwoifyParser
, runParser
)
where
import Prelude
import Control.Monad ((>=>), foldM, replicateM)
import Data.Function ((&))
import Data.List (uncons)
import Data.Owoify.Internal.Entity.Word (InnerWord(InnerWord, innerWord, innerReplacedWords))
import Data.Text.Lazy (Text)
class OwoifyError e where
eof :: e
parseError :: Text -> e
data OError = EOF | ParseError Text deriving (Int -> OError -> ShowS
[OError] -> ShowS
OError -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [OError] -> ShowS
$cshowList :: [OError] -> ShowS
show :: OError -> String
$cshow :: OError -> String
showsPrec :: Int -> OError -> ShowS
$cshowsPrec :: Int -> OError -> ShowS
Show)
instance OwoifyError OError where
eof :: OError
eof = OError
EOF
parseError :: Text -> OError
parseError = Text -> OError
ParseError
type OwoifyResult a = ([Text], a)
type OwoifyFunction e a = OwoifyError e => [Text] -> Either e (OwoifyResult a)
newtype OwoifyParser e a = OwoifyParser (OwoifyFunction e a)
instance Functor (OwoifyParser e) where
fmap :: forall a b. (a -> b) -> OwoifyParser e a -> OwoifyParser e b
fmap a -> b
f (OwoifyParser OwoifyFunction e a
g) = forall e a. OwoifyFunction e a -> OwoifyParser e a
OwoifyParser (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f) forall b c a. (b -> c) -> (a -> b) -> a -> c
. OwoifyFunction e a
g)
instance Applicative (OwoifyParser e) where
<*> :: forall a b.
OwoifyParser e (a -> b) -> OwoifyParser e a -> OwoifyParser e b
(<*>) (OwoifyParser OwoifyFunction e (a -> b)
f) (OwoifyParser OwoifyFunction e a
g) = forall e a. OwoifyFunction e a -> OwoifyParser e a
OwoifyParser (OwoifyFunction e (a -> b)
f forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> \([Text]
s', a -> b
ab) -> OwoifyFunction e a
g [Text]
s' forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \([Text]
s'', a
a) -> forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Text]
s'', a -> b
ab a
a))
pure :: forall a. a -> OwoifyParser e a
pure a
x = forall e a. OwoifyFunction e a -> OwoifyParser e a
OwoifyParser (\[Text]
s -> forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Text]
s, a
x))
instance Monad (OwoifyParser e) where
>>= :: forall a b.
OwoifyParser e a -> (a -> OwoifyParser e b) -> OwoifyParser e b
(>>=) (OwoifyParser OwoifyFunction e a
f) a -> OwoifyParser e b
g = forall e a. OwoifyFunction e a -> OwoifyParser e a
OwoifyParser (OwoifyFunction e a
f forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> \([Text]
s', a
a) -> forall e a.
OwoifyError e =>
OwoifyParser e a -> [Text] -> Either e (OwoifyResult a)
runParser (a -> OwoifyParser e b
g a
a) [Text]
s')
runParser :: OwoifyError e => OwoifyParser e a -> [Text] -> Either e (OwoifyResult a)
runParser :: forall e a.
OwoifyError e =>
OwoifyParser e a -> [Text] -> Either e (OwoifyResult a)
runParser (OwoifyParser OwoifyFunction e a
f) = OwoifyFunction e a
f
word ::
(Foldable t, Monad m, OwoifyError e)
=> t (InnerWord -> m InnerWord)
-> OwoifyParser e (m InnerWord)
word :: forall (t :: * -> *) (m :: * -> *) e.
(Foldable t, Monad m, OwoifyError e) =>
t (InnerWord -> m InnerWord) -> OwoifyParser e (m InnerWord)
word t (InnerWord -> m InnerWord)
mappings = forall e a. OwoifyFunction e a -> OwoifyParser e a
OwoifyParser (\[Text]
s ->
case forall a. [a] -> Maybe (a, [a])
uncons [Text]
s of
Maybe (Text, [Text])
Nothing -> forall a b. a -> Either a b
Left forall e. OwoifyError e => e
eof
Just (Text
head, [Text]
tail) -> do
let w :: InnerWord
w = InnerWord { innerWord :: Text
innerWord = Text
head, innerReplacedWords :: [Text]
innerReplacedWords = [] }
let result :: m InnerWord
result = forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM forall a b. a -> (a -> b) -> b
(&) InnerWord
w t (InnerWord -> m InnerWord)
mappings
forall a b. b -> Either a b
Right ([Text]
tail, m InnerWord
result))
count ::
(Foldable t, Monad m, OwoifyError e)
=> Int
-> t (InnerWord -> m InnerWord)
-> OwoifyParser e [m InnerWord]
count :: forall (t :: * -> *) (m :: * -> *) e.
(Foldable t, Monad m, OwoifyError e) =>
Int -> t (InnerWord -> m InnerWord) -> OwoifyParser e [m InnerWord]
count Int
n t (InnerWord -> m InnerWord)
p | Int
n forall a. Ord a => a -> a -> Bool
<= Int
0 = forall (f :: * -> *) a. Applicative f => a -> f a
pure []
| Bool
otherwise = forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
n forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) (m :: * -> *) e.
(Foldable t, Monad m, OwoifyError e) =>
t (InnerWord -> m InnerWord) -> OwoifyParser e (m InnerWord)
word t (InnerWord -> m InnerWord)
p