module Language.Drasil.Sentence.Fold (
EnumType(..), WrapType(..), SepType(..), FoldType(..),
foldConstraints,
foldlEnumList, foldlList, foldlSP, foldlSP_, foldlSPCol,
foldlSent, foldlSent_, foldlSentCol, foldlsC, foldNums, numList
) where
import Language.Drasil.Classes ( Express(express), Quantity )
import Language.Drasil.Constraint
( Constraint(Range), ConstraintE )
import Language.Drasil.Document ( mkParagraph )
import Language.Drasil.Document.Core ( Contents )
import Language.Drasil.Expr.Class ( ExprC(($&&), realInterval) )
import Language.Drasil.Sentence
( Sentence(S, E, EmptyS, (:+:)), sParen, (+:+), sC, (+:+.), (+:) )
import qualified Language.Drasil.Sentence.Combinators as S (and_, or_)
import Utils.Drasil
foldConstraints :: Quantity c => c -> [ConstraintE] -> Sentence
foldConstraints :: forall c. Quantity c => c -> [ConstraintE] -> Sentence
foldConstraints c
_ [] = Sentence
EmptyS
foldConstraints c
c [ConstraintE]
e = ModelExpr -> Sentence
E forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 forall r. ExprC r => r -> r -> r
($&&) forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall {c}. (Express c, ExprC c) => Constraint c -> ModelExpr
constraintToExpr [ConstraintE]
e
where
constraintToExpr :: Constraint c -> ModelExpr
constraintToExpr (Range ConstraintReason
_ RealInterval c c
ri) = forall c. Express c => c -> ModelExpr
express forall a b. (a -> b) -> a -> b
$ forall r c. (ExprC r, HasUID c) => c -> RealInterval r r -> r
realInterval c
c RealInterval c c
ri
foldlSent :: [Sentence] -> Sentence
foldlSent :: [Sentence] -> Sentence
foldlSent = forall a. (a -> a -> a) -> (a -> a -> a) -> a -> [a] -> a
foldle Sentence -> Sentence -> Sentence
(+:+) Sentence -> Sentence -> Sentence
(+:+.) Sentence
EmptyS
foldlSent_ :: [Sentence] -> Sentence
foldlSent_ :: [Sentence] -> Sentence
foldlSent_ = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl Sentence -> Sentence -> Sentence
(+:+) Sentence
EmptyS
foldlSentCol :: [Sentence] -> Sentence
foldlSentCol :: [Sentence] -> Sentence
foldlSentCol = forall a. (a -> a -> a) -> (a -> a -> a) -> a -> [a] -> a
foldle Sentence -> Sentence -> Sentence
(+:+) Sentence -> Sentence -> Sentence
(+:) Sentence
EmptyS
foldlSP :: [Sentence] -> Contents
foldlSP :: [Sentence] -> Contents
foldlSP = Sentence -> Contents
mkParagraph forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Sentence] -> Sentence
foldlSent
foldlSP_ :: [Sentence] -> Contents
foldlSP_ :: [Sentence] -> Contents
foldlSP_ = Sentence -> Contents
mkParagraph forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Sentence] -> Sentence
foldlSent_
foldlSPCol :: [Sentence] -> Contents
foldlSPCol :: [Sentence] -> Contents
foldlSPCol = Sentence -> Contents
mkParagraph forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Sentence] -> Sentence
foldlSentCol
foldlsC :: [Sentence] -> Sentence
foldlsC :: [Sentence] -> Sentence
foldlsC [] = Sentence
EmptyS
foldlsC [Sentence]
xs = forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldl1 Sentence -> Sentence -> Sentence
sC [Sentence]
xs
data EnumType = Numb | Upper | Lower
data WrapType = Parens | Period
data SepType = Comma | SemiCol
data FoldType = List | Options
foldlList :: SepType -> FoldType -> [Sentence] -> Sentence
foldlList :: SepType -> FoldType -> [Sentence] -> Sentence
foldlList SepType
_ FoldType
_ [] = Sentence
EmptyS
foldlList SepType
_ FoldType
f [Sentence
a, Sentence
b] = FoldType -> Sentence -> Sentence -> Sentence
end FoldType
f Sentence
a Sentence
b
foldlList SepType
s FoldType
f [Sentence]
lst = forall a. (a -> a -> a) -> (a -> a -> a) -> [a] -> a
foldle1 (SepType -> Sentence -> Sentence -> Sentence
sep SepType
s) (\Sentence
a Sentence
b -> FoldType -> Sentence -> Sentence -> Sentence
end FoldType
f (SepType -> Sentence -> Sentence -> Sentence
sep SepType
s Sentence
a Sentence
EmptyS) Sentence
b) [Sentence]
lst
foldlEnumList :: EnumType -> WrapType -> SepType -> FoldType -> [Sentence] -> Sentence
foldlEnumList :: EnumType
-> WrapType -> SepType -> FoldType -> [Sentence] -> Sentence
foldlEnumList EnumType
e WrapType
w SepType
s FoldType
l [Sentence]
lst = SepType -> FoldType -> [Sentence] -> Sentence
foldlList SepType
s FoldType
l forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Sentence -> Sentence -> Sentence
(+:+) (EnumType -> WrapType -> Int -> [Sentence]
enumList EnumType
e WrapType
w forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Int
length [Sentence]
lst) [Sentence]
lst
where
enumList :: EnumType -> WrapType -> Int -> [Sentence]
enumList EnumType
enum WrapType
wt Int
len = forall a b. (a -> b) -> [a] -> [b]
map (WrapType -> Sentence -> Sentence
wrap WrapType
wt forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Sentence
S) (forall a. Int -> [a] -> [a]
take Int
len (EnumType -> [String]
chList EnumType
enum))
chList :: EnumType -> [String]
chList EnumType
Numb = forall a b. (a -> b) -> [a] -> [b]
map forall a. Show a => a -> String
show ([Integer
1..] :: [Integer])
chList EnumType
Upper = forall a b. (a -> b) -> [a] -> [b]
map forall a. Show a => a -> String
show [Char
'A'..Char
'Z']
chList EnumType
Lower = forall a b. (a -> b) -> [a] -> [b]
map forall a. Show a => a -> String
show [Char
'a'..Char
'z']
wrap :: WrapType -> Sentence -> Sentence
wrap WrapType
Parens Sentence
x = Sentence -> Sentence
sParen Sentence
x
wrap WrapType
Period Sentence
x = Sentence
x Sentence -> Sentence -> Sentence
:+: String -> Sentence
S String
"."
end :: FoldType -> (Sentence -> Sentence -> Sentence)
end :: FoldType -> Sentence -> Sentence -> Sentence
end FoldType
List = Sentence -> Sentence -> Sentence
S.and_
end FoldType
Options = Sentence -> Sentence -> Sentence
S.or_
sep :: SepType -> (Sentence -> Sentence -> Sentence)
sep :: SepType -> Sentence -> Sentence -> Sentence
sep SepType
Comma = Sentence -> Sentence -> Sentence
sC
sep SepType
SemiCol = \Sentence
a Sentence
b -> Sentence
a Sentence -> Sentence -> Sentence
:+: String -> Sentence
S String
";" Sentence -> Sentence -> Sentence
+:+ Sentence
b
foldNums :: String -> [Int] -> Sentence
foldNums :: String -> [Int] -> Sentence
foldNums String
s [Int]
x = SepType -> FoldType -> [Sentence] -> Sentence
foldlList SepType
Comma FoldType
List forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map String -> Sentence
S (String -> [Int] -> [String]
numList String
s [Int]
x)
numList :: String -> [Int] -> [String]
numList :: String -> [Int] -> [String]
numList String
_ [] = forall a. HasCallStack => String -> a
error String
"Empty list used with foldNums"
numList String
_ [Int
y] = [forall a. Show a => a -> String
show Int
y]
numList String
s [Int
y, Int
z]
| Int
z forall a. Eq a => a -> a -> Bool
== Int
y forall a. Num a => a -> a -> a
+ Int
1 = [Int -> Int -> String -> String
rangeSep Int
y Int
z String
s]
| Bool
otherwise = forall a b. (a -> b) -> [a] -> [b]
map forall a. Show a => a -> String
show [Int
y, Int
z]
numList String
s (Int
y:Int
z:[Int]
xs)
| Int
z forall a. Eq a => a -> a -> Bool
== Int
y forall a. Num a => a -> a -> a
+ Int
1 = Int -> Int -> [Int] -> [String]
range Int
y Int
z [Int]
xs
| Bool
otherwise = forall a. Show a => a -> String
show Int
y forall a. a -> [a] -> [a]
: String -> [Int] -> [String]
numList String
s (Int
zforall a. a -> [a] -> [a]
:[Int]
xs)
where
range :: Int -> Int -> [Int] -> [String]
range Int
a Int
b [] = [Int -> Int -> String -> String
rangeSep Int
a Int
b String
s]
range Int
a Int
b [Int
n]
| Int
n forall a. Eq a => a -> a -> Bool
== Int
b forall a. Num a => a -> a -> a
+ Int
1 = [Int -> Int -> String -> String
rangeSep Int
a Int
n String
s]
| Bool
otherwise = [Int -> Int -> String -> String
rangeSep Int
a Int
b String
s, forall a. Show a => a -> String
show Int
n]
range Int
a Int
b l :: [Int]
l@(Int
n:[Int]
ns)
| Int
n forall a. Eq a => a -> a -> Bool
== Int
b forall a. Num a => a -> a -> a
+ Int
1 = Int -> Int -> [Int] -> [String]
range Int
a Int
n [Int]
ns
| Bool
otherwise = Int -> Int -> String -> String
rangeSep Int
a Int
b String
s forall a. a -> [a] -> [a]
: String -> [Int] -> [String]
numList String
s [Int]
l
rangeSep :: Int -> Int -> String -> String
rangeSep :: Int -> Int -> String -> String
rangeSep Int
p Int
q String
s = forall a. Show a => a -> String
show Int
p forall a. [a] -> [a] -> [a]
++ String
s forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
q