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, Elem), 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
import Data.Foldable (foldl')
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 (ModelExpr -> Sentence) -> ModelExpr -> Sentence
forall a b. (a -> b) -> a -> b
$ (ModelExpr -> ModelExpr -> ModelExpr) -> [ModelExpr] -> ModelExpr
forall a. (a -> a -> a) -> [a] -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 ModelExpr -> ModelExpr -> ModelExpr
forall r. ExprC r => r -> r -> r
($&&) ([ModelExpr] -> ModelExpr) -> [ModelExpr] -> ModelExpr
forall a b. (a -> b) -> a -> b
$ (ConstraintE -> ModelExpr) -> [ConstraintE] -> [ModelExpr]
forall a b. (a -> b) -> [a] -> [b]
map ConstraintE -> ModelExpr
forall {c}. (Express c, ExprC c) => Constraint c -> ModelExpr
constraintToExpr [ConstraintE]
e
where
constraintToExpr :: Constraint c -> ModelExpr
constraintToExpr (Range ConstraintReason
_ RealInterval c c
ri) = c -> ModelExpr
forall c. Express c => c -> ModelExpr
express (c -> ModelExpr) -> c -> ModelExpr
forall a b. (a -> b) -> a -> b
$ c -> RealInterval c c -> c
forall c. HasUID c => c -> RealInterval c c -> c
forall r c. (ExprC r, HasUID c) => c -> RealInterval r r -> r
realInterval c
c RealInterval c c
ri
constraintToExpr (Elem ConstraintReason
_ c
set) = c -> ModelExpr
forall c. Express c => c -> ModelExpr
express c
set
foldlSent :: [Sentence] -> Sentence
foldlSent :: [Sentence] -> Sentence
foldlSent = (Sentence -> Sentence -> Sentence)
-> (Sentence -> Sentence -> Sentence)
-> Sentence
-> [Sentence]
-> Sentence
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_ = (Sentence -> Sentence -> Sentence)
-> Sentence -> [Sentence] -> Sentence
forall b a. (b -> a -> b) -> b -> [a] -> b
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 = (Sentence -> Sentence -> Sentence)
-> (Sentence -> Sentence -> Sentence)
-> Sentence
-> [Sentence]
-> Sentence
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 (Sentence -> Contents)
-> ([Sentence] -> Sentence) -> [Sentence] -> Contents
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Sentence] -> Sentence
foldlSent
foldlSP_ :: [Sentence] -> Contents
foldlSP_ :: [Sentence] -> Contents
foldlSP_ = Sentence -> Contents
mkParagraph (Sentence -> Contents)
-> ([Sentence] -> Sentence) -> [Sentence] -> Contents
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Sentence] -> Sentence
foldlSent_
foldlSPCol :: [Sentence] -> Contents
foldlSPCol :: [Sentence] -> Contents
foldlSPCol = Sentence -> Contents
mkParagraph (Sentence -> Contents)
-> ([Sentence] -> Sentence) -> [Sentence] -> Contents
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 = (Sentence -> Sentence -> Sentence) -> [Sentence] -> Sentence
forall a. (a -> a -> a) -> [a] -> a
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 = (Sentence -> Sentence -> Sentence)
-> (Sentence -> Sentence -> Sentence) -> [Sentence] -> Sentence
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 ([Sentence] -> Sentence) -> [Sentence] -> Sentence
forall a b. (a -> b) -> a -> b
$ (Sentence -> Sentence -> Sentence)
-> [Sentence] -> [Sentence] -> [Sentence]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Sentence -> Sentence -> Sentence
(+:+) (EnumType -> WrapType -> Int -> [Sentence]
enumList EnumType
e WrapType
w (Int -> [Sentence]) -> Int -> [Sentence]
forall a b. (a -> b) -> a -> b
$ [Sentence] -> Int
forall a. [a] -> Int
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 = (String -> Sentence) -> [String] -> [Sentence]
forall a b. (a -> b) -> [a] -> [b]
map (WrapType -> Sentence -> Sentence
wrap WrapType
wt (Sentence -> Sentence)
-> (String -> Sentence) -> String -> Sentence
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Sentence
S) (Int -> [String] -> [String]
forall a. Int -> [a] -> [a]
take Int
len (EnumType -> [String]
chList EnumType
enum))
chList :: EnumType -> [String]
chList EnumType
Numb = (Integer -> String) -> [Integer] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Integer -> String
forall a. Show a => a -> String
show ([Integer
1..] :: [Integer])
chList EnumType
Upper = (Char -> String) -> String -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Char -> String
forall a. Show a => a -> String
show [Char
'A'..Char
'Z']
chList EnumType
Lower = (Char -> String) -> String -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Char -> String
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 ([Sentence] -> Sentence) -> [Sentence] -> Sentence
forall a b. (a -> b) -> a -> b
$ (String -> Sentence) -> [String] -> [Sentence]
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
_ [] = String -> [String]
forall a. HasCallStack => String -> a
error String
"Empty list used with foldNums"
numList String
_ [Int
y] = [Int -> String
forall a. Show a => a -> String
show Int
y]
numList String
s [Int
y, Int
z]
| Int
z Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1 = [Int -> Int -> String -> String
rangeSep Int
y Int
z String
s]
| Bool
otherwise = (Int -> String) -> [Int] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Int -> String
forall a. Show a => a -> String
show [Int
y, Int
z]
numList String
s (Int
y:Int
z:[Int]
xs)
| Int
z Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1 = Int -> Int -> [Int] -> [String]
range Int
y Int
z [Int]
xs
| Bool
otherwise = Int -> String
forall a. Show a => a -> String
show Int
y String -> [String] -> [String]
forall a. a -> [a] -> [a]
: String -> [Int] -> [String]
numList String
s (Int
zInt -> [Int] -> [Int]
forall 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 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
b Int -> Int -> Int
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, Int -> String
forall a. Show a => a -> String
show Int
n]
range Int
a Int
b l :: [Int]
l@(Int
n:[Int]
ns)
| Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
b Int -> Int -> Int
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 String -> [String] -> [String]
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 = Int -> String
forall a. Show a => a -> String
show Int
p String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
q