{-# LANGUAGE RankNTypes, ViewPatterns #-}
module Test.Tasty.Patterns.Eval (Path, eval, withFields, asB) where
import Prelude hiding (Ordering(..))
import Control.Monad.Reader
import Control.Monad.Error.Class (throwError)
import qualified Data.Sequence as Seq
import Data.Foldable
import Data.List
import Data.Maybe
import Data.Char
import Test.Tasty.Patterns.Types
#if !MIN_VERSION_base(4,9,0)
import Control.Applicative
import Data.Traversable
#endif
type Path = Seq.Seq String
data Value
= VN !Int
| VS !Bool String
| Uninitialized
deriving Int -> Value -> ShowS
[Value] -> ShowS
Value -> String
(Int -> Value -> ShowS)
-> (Value -> String) -> ([Value] -> ShowS) -> Show Value
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Value] -> ShowS
$cshowList :: [Value] -> ShowS
show :: Value -> String
$cshow :: Value -> String
showsPrec :: Int -> Value -> ShowS
$cshowsPrec :: Int -> Value -> ShowS
Show
type M = ReaderT Path (Either String)
asS :: Value -> M String
asS :: Value -> M String
asS Value
v = String -> M String
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> M String) -> String -> M String
forall a b. (a -> b) -> a -> b
$
case Value
v of
VN Int
n -> Int -> String
forall a. Show a => a -> String
show Int
n
VS Bool
_ String
s -> String
s
Value
Uninitialized -> String
""
parseN :: String -> Maybe Int
parseN :: String -> Maybe Int
parseN String
s =
case String -> [(Int, String)]
forall a. Read a => String -> a
read String
s of
[(Int
n, String
"")] -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
n
[(Int, String)]
_ -> Maybe Int
forall a. Maybe a
Nothing
asN :: Value -> M Int
asN :: Value -> M Int
asN Value
v =
case Value
v of
VN Int
n -> Int -> M Int
forall (m :: * -> *) a. Monad m => a -> m a
return Int
n
VS Bool
True String
s ->
case String -> Maybe Int
parseN String
s of
Just Int
n -> Int -> M Int
forall (m :: * -> *) a. Monad m => a -> m a
return Int
n
Maybe Int
Nothing -> String -> M Int
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (String -> M Int) -> String -> M Int
forall a b. (a -> b) -> a -> b
$ String
"Not a number: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ShowS
forall a. Show a => a -> String
show String
s
VS Bool
False String
s -> String -> M Int
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (String -> M Int) -> String -> M Int
forall a b. (a -> b) -> a -> b
$ String
"String is not numeric: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ShowS
forall a. Show a => a -> String
show String
s
Value
Uninitialized -> Int -> M Int
forall (m :: * -> *) a. Monad m => a -> m a
return Int
0
isN :: Value -> Bool
isN :: Value -> Bool
isN Value
v =
case Value
v of
VN Int
_ -> Bool
True
Value
_ -> Bool
False
isNumeric :: Value -> Bool
isNumeric :: Value -> Bool
isNumeric Value
v =
case Value
v of
VS Bool
b String
s -> Bool
b Bool -> Bool -> Bool
&& Maybe Int -> Bool
forall a. Maybe a -> Bool
isJust (String -> Maybe Int
parseN String
s)
Value
_ -> Bool
True
asB :: Value -> M Bool
asB :: Value -> M Bool
asB Value
v = Bool -> M Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> M Bool) -> Bool -> M Bool
forall a b. (a -> b) -> a -> b
$
case Value
v of
VN Int
0 -> Bool
False
VS Bool
_ String
"" -> Bool
False
Value
_ -> Bool
True
fromB :: Bool -> Value
fromB :: Bool -> Value
fromB = Int -> Value
VN (Int -> Value) -> (Bool -> Int) -> Bool -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Int
forall a. Enum a => a -> Int
fromEnum
eval :: Expr -> M Value
eval :: Expr -> M Value
eval Expr
e0 =
case Expr
e0 of
IntLit Int
n -> Value -> M Value
forall (m :: * -> *) a. Monad m => a -> m a
return (Value -> M Value) -> Value -> M Value
forall a b. (a -> b) -> a -> b
$ Int -> Value
VN Int
n
StringLit String
s -> Value -> M Value
forall (m :: * -> *) a. Monad m => a -> m a
return (Value -> M Value) -> Value -> M Value
forall a b. (a -> b) -> a -> b
$ Bool -> String -> Value
VS Bool
False String
s
Expr
NF -> Int -> Value
VN (Int -> Value) -> (Seq String -> Int) -> Seq String -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Int -> Int
forall a. Num a => a -> a -> a
subtract Int
1 (Int -> Int) -> (Seq String -> Int) -> Seq String -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Seq String -> Int
forall a. Seq a -> Int
Seq.length (Seq String -> Value)
-> ReaderT (Seq String) (Either String) (Seq String) -> M Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReaderT (Seq String) (Either String) (Seq String)
forall r (m :: * -> *). MonadReader r m => m r
ask
Add Expr
e1 Expr
e2 -> (Int -> Int -> Int) -> Expr -> Expr -> M Value
binNumOp Int -> Int -> Int
forall a. Num a => a -> a -> a
(+) Expr
e1 Expr
e2
Sub Expr
e1 Expr
e2 -> (Int -> Int -> Int) -> Expr -> Expr -> M Value
binNumOp (-) Expr
e1 Expr
e2
Neg Expr
e1 -> Int -> Value
VN (Int -> Value) -> (Int -> Int) -> Int -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Int
forall a. Num a => a -> a
negate (Int -> Value) -> M Int -> M Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Value -> M Int
asN (Value -> M Int) -> M Value -> M Int
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Expr -> M Value
eval Expr
e1)
Not Expr
e1 -> Bool -> Value
fromB (Bool -> Value) -> (Bool -> Bool) -> Bool -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Bool
not (Bool -> Value) -> M Bool -> M Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Value -> M Bool
asB (Value -> M Bool) -> M Value -> M Bool
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Expr -> M Value
eval Expr
e1)
And Expr
e1 Expr
e2 -> (Bool -> Bool -> Bool) -> Expr -> Expr -> M Value
binLglOp Bool -> Bool -> Bool
(&&) Expr
e1 Expr
e2
Or Expr
e1 Expr
e2 -> (Bool -> Bool -> Bool) -> Expr -> Expr -> M Value
binLglOp Bool -> Bool -> Bool
(||) Expr
e1 Expr
e2
LT Expr
e1 Expr
e2 -> (forall a. Ord a => a -> a -> Bool) -> Expr -> Expr -> M Value
binCmpOp forall a. Ord a => a -> a -> Bool
(<) Expr
e1 Expr
e2
LE Expr
e1 Expr
e2 -> (forall a. Ord a => a -> a -> Bool) -> Expr -> Expr -> M Value
binCmpOp forall a. Ord a => a -> a -> Bool
(<=) Expr
e1 Expr
e2
GT Expr
e1 Expr
e2 -> (forall a. Ord a => a -> a -> Bool) -> Expr -> Expr -> M Value
binCmpOp forall a. Ord a => a -> a -> Bool
(>) Expr
e1 Expr
e2
GE Expr
e1 Expr
e2 -> (forall a. Ord a => a -> a -> Bool) -> Expr -> Expr -> M Value
binCmpOp forall a. Ord a => a -> a -> Bool
(>=) Expr
e1 Expr
e2
EQ Expr
e1 Expr
e2 -> (forall a. Ord a => a -> a -> Bool) -> Expr -> Expr -> M Value
binCmpOp forall a. Eq a => a -> a -> Bool
forall a. Ord a => a -> a -> Bool
(==) Expr
e1 Expr
e2
NE Expr
e1 Expr
e2 -> (forall a. Ord a => a -> a -> Bool) -> Expr -> Expr -> M Value
binCmpOp forall a. Eq a => a -> a -> Bool
forall a. Ord a => a -> a -> Bool
(/=) Expr
e1 Expr
e2
Concat Expr
e1 Expr
e2 -> Bool -> String -> Value
VS Bool
False (String -> Value) -> M String -> M Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (String -> ShowS
forall a. [a] -> [a] -> [a]
(++) (String -> ShowS)
-> M String -> ReaderT (Seq String) (Either String) ShowS
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Value -> M String
asS (Value -> M String) -> M Value -> M String
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Expr -> M Value
eval Expr
e1) ReaderT (Seq String) (Either String) ShowS -> M String -> M String
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Value -> M String
asS (Value -> M String) -> M Value -> M String
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Expr -> M Value
eval Expr
e2))
If Expr
cond Expr
e1 Expr
e2 -> do
Bool
condV <- Value -> M Bool
asB (Value -> M Bool) -> M Value -> M Bool
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Expr -> M Value
eval Expr
cond
if Bool
condV then Expr -> M Value
eval Expr
e1 else Expr -> M Value
eval Expr
e2
Field Expr
e1 -> do
Int
n <- Value -> M Int
asN (Value -> M Int) -> M Value -> M Int
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Expr -> M Value
eval Expr
e1
Seq String
fields <- ReaderT (Seq String) (Either String) (Seq String)
forall r (m :: * -> *). MonadReader r m => m r
ask
Value -> M Value
forall (m :: * -> *) a. Monad m => a -> m a
return (Value -> M Value) -> Value -> M Value
forall a b. (a -> b) -> a -> b
$ if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Seq String -> Int
forall a. Seq a -> Int
Seq.length Seq String
fields Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
then Value
Uninitialized
else Bool -> String -> Value
VS Bool
True (String -> Value) -> String -> Value
forall a b. (a -> b) -> a -> b
$ Seq String -> Int -> String
forall a. Seq a -> Int -> a
Seq.index Seq String
fields Int
n
ERE String
pat -> do
String
str <- Seq String -> Int -> String
forall a. Seq a -> Int -> a
Seq.index (Seq String -> Int -> String)
-> ReaderT (Seq String) (Either String) (Seq String)
-> ReaderT (Seq String) (Either String) (Int -> String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReaderT (Seq String) (Either String) (Seq String)
forall r (m :: * -> *). MonadReader r m => m r
ask ReaderT (Seq String) (Either String) (Int -> String)
-> M Int -> M String
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> M Int
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
0
Value -> M Value
forall (m :: * -> *) a. Monad m => a -> m a
return (Value -> M Value) -> (Bool -> Value) -> Bool -> M Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Value
fromB (Bool -> M Value) -> Bool -> M Value
forall a b. (a -> b) -> a -> b
$ String -> String -> Bool
match String
pat String
str
Match Expr
e1 String
pat -> do
String
str <- Value -> M String
asS (Value -> M String) -> M Value -> M String
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Expr -> M Value
eval Expr
e1
Value -> M Value
forall (m :: * -> *) a. Monad m => a -> m a
return (Value -> M Value) -> (Bool -> Value) -> Bool -> M Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Value
fromB (Bool -> M Value) -> Bool -> M Value
forall a b. (a -> b) -> a -> b
$ String -> String -> Bool
match String
pat String
str
NoMatch Expr
e1 String
pat -> do
String
str <- Value -> M String
asS (Value -> M String) -> M Value -> M String
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Expr -> M Value
eval Expr
e1
Value -> M Value
forall (m :: * -> *) a. Monad m => a -> m a
return (Value -> M Value) -> (Bool -> Value) -> Bool -> M Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Value
fromB (Bool -> Value) -> (Bool -> Bool) -> Bool -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Bool
not (Bool -> M Value) -> Bool -> M Value
forall a b. (a -> b) -> a -> b
$ String -> String -> Bool
match String
pat String
str
ToUpperFn Expr
e1 ->
Bool -> String -> Value
VS Bool
True (String -> Value) -> ShowS -> String -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Char) -> ShowS
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toUpper (String -> Value) -> M String -> M Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Value -> M String
asS (Value -> M String) -> M Value -> M String
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Expr -> M Value
eval Expr
e1)
ToLowerFn Expr
e1 ->
Bool -> String -> Value
VS Bool
True (String -> Value) -> ShowS -> String -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Char) -> ShowS
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower (String -> Value) -> M String -> M Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Value -> M String
asS (Value -> M String) -> M Value -> M String
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Expr -> M Value
eval Expr
e1)
SubstrFn Expr
e1 Expr
e2 Maybe Expr
mb_e3 -> do
String
s <- Value -> M String
asS (Value -> M String) -> M Value -> M String
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Expr -> M Value
eval Expr
e1
Int
m <- Value -> M Int
asN (Value -> M Int) -> M Value -> M Int
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Expr -> M Value
eval Expr
e2
Maybe Int
mb_n <- (Expr -> M Int)
-> Maybe Expr -> ReaderT (Seq String) (Either String) (Maybe Int)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (Value -> M Int
asN (Value -> M Int) -> (Expr -> M Value) -> Expr -> M Int
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Expr -> M Value
eval) Maybe Expr
mb_e3
Value -> M Value
forall (m :: * -> *) a. Monad m => a -> m a
return (Value -> M Value) -> Value -> M Value
forall a b. (a -> b) -> a -> b
$ Bool -> String -> Value
VS Bool
True (String -> Value) -> String -> Value
forall a b. (a -> b) -> a -> b
$
ShowS -> (Int -> ShowS) -> Maybe Int -> ShowS
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ShowS
forall a. a -> a
id Int -> ShowS
forall a. Int -> [a] -> [a]
take Maybe Int
mb_n ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
forall a. Int -> [a] -> [a]
drop (Int
mInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ String
s
LengthFn (Expr -> Maybe Expr -> Expr
forall a. a -> Maybe a -> a
fromMaybe (Expr -> Expr
Field (Int -> Expr
IntLit Int
0)) -> Expr
e1) ->
Int -> Value
VN (Int -> Value) -> (String -> Int) -> String -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (String -> Value) -> M String -> M Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Value -> M String
asS (Value -> M String) -> M Value -> M String
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Expr -> M Value
eval Expr
e1)
MatchFn Expr
e1 String
pat -> do
String
s <- Value -> M String
asS (Value -> M String) -> M Value -> M String
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Expr -> M Value
eval Expr
e1
Value -> M Value
forall (m :: * -> *) a. Monad m => a -> m a
return (Value -> M Value) -> ([String] -> Value) -> [String] -> M Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Value
VN (Int -> Value) -> ([String] -> Int) -> [String] -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> (Int -> Int) -> Maybe Int -> Int
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Int
0 (Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) (Maybe Int -> Int) -> ([String] -> Maybe Int) -> [String] -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> Bool) -> [String] -> Maybe Int
forall a. (a -> Bool) -> [a] -> Maybe Int
findIndex (String
pat String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf`) ([String] -> M Value) -> [String] -> M Value
forall a b. (a -> b) -> a -> b
$ String -> [String]
forall a. [a] -> [[a]]
tails String
s
where
binNumOp :: (Int -> Int -> Int) -> Expr -> Expr -> M Value
binNumOp Int -> Int -> Int
op Expr
e1 Expr
e2 = Int -> Value
VN (Int -> Value) -> M Int -> M Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Int -> Int -> Int
op (Int -> Int -> Int)
-> M Int -> ReaderT (Seq String) (Either String) (Int -> Int)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Value -> M Int
asN (Value -> M Int) -> M Value -> M Int
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Expr -> M Value
eval Expr
e1) ReaderT (Seq String) (Either String) (Int -> Int) -> M Int -> M Int
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Value -> M Int
asN (Value -> M Int) -> M Value -> M Int
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Expr -> M Value
eval Expr
e2))
binLglOp :: (Bool -> Bool -> Bool) -> Expr -> Expr -> M Value
binLglOp Bool -> Bool -> Bool
op Expr
e1 Expr
e2 = Bool -> Value
fromB (Bool -> Value) -> M Bool -> M Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Bool -> Bool -> Bool
op (Bool -> Bool -> Bool)
-> M Bool -> ReaderT (Seq String) (Either String) (Bool -> Bool)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Value -> M Bool
asB (Value -> M Bool) -> M Value -> M Bool
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Expr -> M Value
eval Expr
e1) ReaderT (Seq String) (Either String) (Bool -> Bool)
-> M Bool -> M Bool
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Value -> M Bool
asB (Value -> M Bool) -> M Value -> M Bool
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Expr -> M Value
eval Expr
e2))
binCmpOp :: (forall a . Ord a => a -> a -> Bool) -> Expr -> Expr -> M Value
binCmpOp :: (forall a. Ord a => a -> a -> Bool) -> Expr -> Expr -> M Value
binCmpOp forall a. Ord a => a -> a -> Bool
op Expr
e1 Expr
e2 = do
Value
v1 <- Expr -> M Value
eval Expr
e1
Value
v2 <- Expr -> M Value
eval Expr
e2
let
compareAsNumbers :: Bool
compareAsNumbers =
Value -> Bool
isN Value
v1 Bool -> Bool -> Bool
&& Value -> Bool
isNumeric Value
v2 Bool -> Bool -> Bool
||
Value -> Bool
isN Value
v2 Bool -> Bool -> Bool
&& Value -> Bool
isNumeric Value
v1
if Bool
compareAsNumbers
then Bool -> Value
fromB (Bool -> Value) -> M Bool -> M Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
op (Int -> Int -> Bool)
-> M Int -> ReaderT (Seq String) (Either String) (Int -> Bool)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> M Int
asN Value
v1 ReaderT (Seq String) (Either String) (Int -> Bool)
-> M Int -> M Bool
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Value -> M Int
asN Value
v2)
else Bool -> Value
fromB (Bool -> Value) -> M Bool -> M Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (String -> String -> Bool
forall a. Ord a => a -> a -> Bool
op (String -> String -> Bool)
-> M String
-> ReaderT (Seq String) (Either String) (String -> Bool)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> M String
asS Value
v1 ReaderT (Seq String) (Either String) (String -> Bool)
-> M String -> M Bool
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Value -> M String
asS Value
v2)
match
:: String
-> String
-> Bool
match :: String -> String -> Bool
match String
pat String
str = String
pat String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isInfixOf` String
str
withFields :: Seq.Seq String -> M a -> Either String a
withFields :: Seq String -> M a -> Either String a
withFields Seq String
fields M a
a = M a -> Seq String -> Either String a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT M a
a (String
whole String -> Seq String -> Seq String
forall a. a -> Seq a -> Seq a
Seq.<| Seq String
fields)
where whole :: String
whole = String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"." ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ Seq String -> [String]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList Seq String
fields