{-# LANGUAGE ApplicativeDo #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilyDependencies #-}
{-# LANGUAGE TypeOperators #-}
{-# OPTIONS_GHC -Wwarn=star-is-type #-}
{-# OPTIONS_GHC -Wno-orphans #-}
-- | This module provides common skeletons for printing tasks
module Control.OutputCapable.Blocks (
  FunctorTrans (..),
  -- * Report monad
  GenericOut (..),
  GenericReportT (..),
  Language (..),
  Out,
  ReportT,
  Report,
  getAllOuts,
  getOutsWithResult,
  toOutput,
  -- * Monad for translations
  GenericLangM (LangM, unLangM),
  LangM',
  LangM,
  Rated,
  -- * Output monad
  GenericOutputCapable (..),
  OutputCapable,
  enumerate,
  abortWith,
  alignOutput,
  combineReports,
  combineTwoReports,
  format,
  recoverFrom,
  recoverWith,
  toAbort,
  -- * Translation
  ArticleToUse (..),
  collapsed,
  english,
  german,
  localise,
  mapLangM,
  multiLang,
  translate,
  translateCode,
  translations,
  -- * Helpers
  -- ** Additional Text
  ExtraText (..),
  extra,
  -- * Other helpers
  MinimumThreshold (..),
  Punishment (..),
  TargetedCorrect (..),
  ($=<<),
  extendedMultipleChoice,
  multipleChoice,
  multipleChoiceSyntax,
  printSolutionAndAssert,
  printSolutionAndAssertWithMinimum,
  reRefuse,
  reRefuseLangM,
  singleChoice,
  singleChoiceSyntax,
  continueOrAbort,
  yesNo,
  ) where


import qualified Control.OutputCapable.Blocks.Generic as Generic (
  alignOutput,
  collapsed,
  combineReports,
  combineTwoReports,
  toAbort,
  translate,
  translateCode,
  translations,
  )
import qualified Data.Map as M

import Autolib.Hash                     (Hashable)
import Autolib.Reader                   (Reader)
import Autolib.ToDoc                    (ToDoc)
import Control.Functor.Trans            (FunctorTrans (lift))
import Control.Monad.State              (put)
import Control.OutputCapable.Blocks.Generic (
  GenericLangM (..),
  GenericOutputCapable (..),
  GenericReportT (..),
  RunnableOutputCapable (..),
  ($=<<),
  ($>>),
  ($>>=),
  abortWith,
  format,
  mapLangM,
  recoverFrom,
  recoverWith,
  runLangMReport,
  )
import Control.OutputCapable.Blocks.Report (
  GenericOut (..),
  Language (..),
  Out,
  ReportT,
  Report,
  getAllOuts,
  getOutsWithResult,
  toOutput,
  )

import Control.Applicative              (Alternative)
import Control.Monad                    (unless, void, when)
import Control.Monad.State              (State, modify)
import Control.Monad.Writer (
  MonadWriter (tell),
  )
import Data.Containers.ListUtils        (nubOrd)
import Data.Data                        (Data)
import Data.Foldable                    (for_, traverse_)
import Data.Map                         (Map,foldrWithKey)
import Data.Maybe                       (fromMaybe, isJust)
import Data.Ratio                       ((%))
import GHC.Generics                     (Generic)

{-|
If argument is 'True',
it will continue after assertion,
otherwise it will stop if assertion fails.
-}
continueOrAbort :: OutputCapable m => Bool -> Bool -> LangM m -> LangM m
continueOrAbort :: forall (m :: * -> *).
OutputCapable m =>
Bool -> Bool -> LangM m -> LangM m
continueOrAbort Bool
True  = Bool -> LangM m -> LangM m
forall (m :: * -> *). OutputCapable m => Bool -> LangM m -> LangM m
yesNo
continueOrAbort Bool
False = Bool -> LangM m -> LangM m
forall l (m :: * -> *).
GenericOutputCapable l m =>
Bool -> GenericLangM l m () -> GenericLangM l m ()
assertion

{-|
In contrast to 'assertion' it will only indicate that a check was performed
and its result.
However, it will not abort.
-}
yesNo :: OutputCapable m => Bool -> LangM m -> LangM m
yesNo :: forall (m :: * -> *). OutputCapable m => Bool -> LangM m -> LangM m
yesNo Bool
p LangM m
q = do
  LangM m -> LangM m
forall l (m :: * -> *).
GenericOutputCapable l m =>
GenericLangM l m () -> GenericLangM l m ()
paragraph LangM m
q
  LangM m -> LangM m
forall l (m :: * -> *).
GenericOutputCapable l m =>
GenericLangM l m () -> GenericLangM l m ()
paragraph (LangM m -> LangM m) -> LangM m -> LangM m
forall a b. (a -> b) -> a -> b
$ LangM m -> LangM m
forall l (m :: * -> *).
GenericOutputCapable l m =>
GenericLangM l m () -> GenericLangM l m ()
indent (LangM m -> LangM m) -> LangM m -> LangM m
forall a b. (a -> b) -> a -> b
$ (Language -> String) -> LangM m
forall l (m :: * -> *).
GenericOutputCapable l m =>
(l -> String) -> GenericLangM l m ()
translatedCode ((Language -> String) -> LangM m)
-> (Language -> String) -> LangM m
forall a b. (a -> b) -> a -> b
$ (Language -> Map Language String -> String)
-> Map Language String -> Language -> String
forall a b c. (a -> b -> c) -> b -> a -> c
flip Language -> Map Language String -> String
localise (Map Language String -> Language -> String)
-> Map Language String -> Language -> String
forall a b. (a -> b) -> a -> b
$ State (Map Language String) () -> Map Language String
forall l a. State (Map l a) () -> Map l a
translations (State (Map Language String) () -> Map Language String)
-> State (Map Language String) () -> Map Language String
forall a b. (a -> b) -> a -> b
$
      if Bool
p
      then do
        String -> State (Map Language String) ()
english String
"Yes."
        String -> State (Map Language String) ()
german String
"Ja."
      else do
        String -> State (Map Language String) ()
english String
"No."
        String -> State (Map Language String) ()
german String
"Nein."
  pure ()

{-|
A 'Rational' number indicating the minimal threshold.
-}
newtype MinimumThreshold = MinimumThreshold {
  MinimumThreshold -> Rational
unMinimumThreshold :: Rational
  }

{-|
A 'Rational' number indicating the punishment.
-}
newtype Punishment = Punishment {
  Punishment -> Rational
unPunishment :: Rational
  }

{-|
A 'Int' number indicating expected correct answers.
-}
newtype TargetedCorrect = TargetedCorrect {
  TargetedCorrect -> Int
unTargetedCorrect :: Int
  }

{-|
Outputs feedback on syntax of a multiple choice submission.
Depending on chosen parameters it might reject the submission.
-}
multipleChoiceSyntax
  :: (OutputCapable m, Ord a, Show a)
  => Bool
  -- ^ whether to continue after check (i.e. do not reject wrong answers)
  -> [a]
  -- ^ possible answers
  -> [a]
  -- ^ the submission to evaluate
  -> LangM m
multipleChoiceSyntax :: forall (m :: * -> *) a.
(OutputCapable m, Ord a, Show a) =>
Bool -> [a] -> [a] -> LangM m
multipleChoiceSyntax Bool
withSolution [a]
options =
  (a -> GenericLangM Language m ())
-> [a] -> GenericLangM Language m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (Bool -> [a] -> a -> GenericLangM Language m ()
forall (m :: * -> *) a.
(OutputCapable m, Eq a, Show a) =>
Bool -> [a] -> a -> LangM m
singleChoiceSyntax Bool
withSolution [a]
options) ([a] -> GenericLangM Language m ())
-> ([a] -> [a]) -> [a] -> GenericLangM Language m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> [a]
forall a. Ord a => [a] -> [a]
nubOrd

{-|
Evaluates multiple choice submissions
by rejecting correctness below 50 percent.
(see 'extendedMultipleChoice')
-}
multipleChoice
  :: (OutputCapable m, Ord a)
  => Map Language String
  -- ^ what is asked for
  -> Maybe (ArticleToUse, String)
  -- ^ the correct solution to show,
  -- and the article kind indicating if multiple different solutions could be possible
  -> Map a Bool
  -- ^ possible answers and if they are correct
  -> [a]
  -- ^ the submission to evaluate
  -> Rated m
multipleChoice :: forall (m :: * -> *) a.
(OutputCapable m, Ord a) =>
Map Language String
-> Maybe (ArticleToUse, String) -> Map a Bool -> [a] -> Rated m
multipleChoice Map Language String
what Maybe (ArticleToUse, String)
optionalSolution Map a Bool
solution =
  MinimumThreshold
-> Punishment
-> TargetedCorrect
-> Maybe (Map Language String)
-> Maybe (ArticleToUse, String)
-> Map a Bool
-> Map a Bool
-> Rated m
forall (m :: * -> *) a.
(OutputCapable m, Ord a) =>
MinimumThreshold
-> Punishment
-> TargetedCorrect
-> Maybe (Map Language String)
-> Maybe (ArticleToUse, String)
-> Map a Bool
-> Map a Bool
-> Rated m
extendedMultipleChoice
  (Rational -> MinimumThreshold
MinimumThreshold (Integer
1 Integer -> Integer -> Rational
forall a. Integral a => a -> a -> Ratio a
% Integer
2))
  (Rational -> Punishment
Punishment Rational
0)
  (Int -> TargetedCorrect
TargetedCorrect (Map a Bool -> Int
forall a. Map a a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length Map a Bool
solution))
  (Map Language String -> Maybe (Map Language String)
forall a. a -> Maybe a
Just Map Language String
what)
  Maybe (ArticleToUse, String)
optionalSolution
  Map a Bool
solution
  (Map a Bool -> Rated m) -> ([a] -> Map a Bool) -> [a] -> Rated m
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Map a Bool -> Map a Bool) -> Map a Bool -> [a] -> Map a Bool
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (a -> Bool -> Map a Bool -> Map a Bool
forall k a. Ord k => k -> a -> Map k a -> Map k a
`M.insert` Bool
True) ((Bool -> Bool) -> Map a Bool -> Map a Bool
forall a k. (a -> Bool) -> Map k a -> Map k a
M.filter Bool -> Bool
not Map a Bool
solution)

{-|
Evaluates multiple choice submissions
by rejecting correctness below a minimum threshold.


The following preconditions need to hold before calling this function
but are not checked:

 * targeted correct is at least one
   and not larger than the amount of possible answers
-}
extendedMultipleChoice
  :: (OutputCapable m, Ord a)
  => MinimumThreshold
  -- ^ the minimum threshold of achieved points
  -> Punishment
  -- ^ points to subtract per wrong answer
  -> TargetedCorrect
  -- ^ how many correct answers have to be given within the submission
  -- in order to achieve full points
  -> Maybe (Map Language String)
  -- ^ what is asked for (Nothing suppresses correctness and exhaustiveness checking output)
  -> Maybe (ArticleToUse, String)
  -- ^ the correct solution to show,
  -- and the article kind indicating if multiple different solutions could be possible
  -> Map a Bool
  -- ^ possible answers and if they are correct
  -> Map a Bool
  -- ^ the submission to evaluate
  -> Rated m
extendedMultipleChoice :: forall (m :: * -> *) a.
(OutputCapable m, Ord a) =>
MinimumThreshold
-> Punishment
-> TargetedCorrect
-> Maybe (Map Language String)
-> Maybe (ArticleToUse, String)
-> Map a Bool
-> Map a Bool
-> Rated m
extendedMultipleChoice
  MinimumThreshold
minimumPoints
  Punishment
punishment
  TargetedCorrect
targeted
  Maybe (Map Language String)
what
  Maybe (ArticleToUse, String)
optionalSolution
  Map a Bool
solution
  Map a Bool
choices
  = case Maybe (Map Language String)
what of
      Maybe (Map Language String)
Nothing ->
        Bool -> Rated m
theGrading Bool
False
      Just Map Language String
things ->
        Map Language String -> LangM m
correctnessCheck Map Language String
things
        LangM m -> LangM m -> LangM m
forall a b.
GenericLangM Language m a
-> GenericLangM Language m b -> GenericLangM Language m b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Map Language String -> LangM m
exhaustivenessCheck Map Language String
things
        LangM m -> Rated m -> Rated m
forall a b.
GenericLangM Language m a
-> GenericLangM Language m b -> GenericLangM Language m b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Bool -> Rated m
theGrading Bool
True
  where
    madeUp :: Map a Bool
madeUp = Map a Bool -> Map a Bool -> Map a Bool
forall k a b. Ord k => Map k a -> Map k b -> Map k a
M.difference Map a Bool
choices Map a Bool
solution
    chosenTrue :: Map a Bool
chosenTrue = Map a Bool -> Map a Bool -> Map a Bool
forall k a b. Ord k => Map k a -> Map k b -> Map k a
M.intersection Map a Bool
solution (Map a Bool -> Map a Bool) -> Map a Bool -> Map a Bool
forall a b. (a -> b) -> a -> b
$ (Bool -> Bool) -> Map a Bool -> Map a Bool
forall a k. (a -> Bool) -> Map k a -> Map k a
M.filter Bool -> Bool
forall a. a -> a
id Map a Bool
choices
    isCorrect :: Bool
isCorrect = Map a Bool -> Bool
forall k a. Map k a -> Bool
M.null Map a Bool
madeUp Bool -> Bool -> Bool
&& Map a Bool -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and Map a Bool
chosenTrue
    theGrading :: Bool -> Rated m
theGrading Bool
mentionExhaustiveness = MinimumThreshold
-> Bool -> Maybe (ArticleToUse, String) -> Rational -> Rated m
forall (m :: * -> *).
OutputCapable m =>
MinimumThreshold
-> Bool -> Maybe (ArticleToUse, String) -> Rational -> Rated m
printSolutionAndAssertWithMinimum
      MinimumThreshold
minimumPoints
      Bool
mentionExhaustiveness
      Maybe (ArticleToUse, String)
optionalSolution
      (Rational -> Rated m) -> Rational -> Rated m
forall a b. (a -> b) -> a -> b
$ Punishment
-> TargetedCorrect -> Map a Bool -> Map a Bool -> Rational
forall k.
Ord k =>
Punishment
-> TargetedCorrect -> Map k Bool -> Map k Bool -> Rational
gradeMultipleChoice Punishment
punishment TargetedCorrect
targeted Map a Bool
solution Map a Bool
choices
    correctnessCheck :: Map Language String -> LangM m
correctnessCheck Map Language String
things = Bool -> LangM m -> LangM m
forall (m :: * -> *). OutputCapable m => Bool -> LangM m -> LangM m
yesNo Bool
isCorrect (LangM m -> LangM m) -> LangM m -> LangM m
forall a b. (a -> b) -> a -> b
$ [(Language, String)] -> LangM m
forall (m :: * -> *).
OutputCapable m =>
[(Language, String)] -> LangM m
multiLang [
      (Language
English, String
"All indicated " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Language -> Map Language String -> String
localise Language
English Map Language String
things String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" are correct?"),
      (Language
German, String
"Alle angegebenen " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Language -> Map Language String -> String
localise Language
German Map Language String
things String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" sind korrekt?")
      ]
    answers :: Map a Bool
answers = (Bool -> Bool -> Bool) -> Map a Bool -> Map a Bool -> Map a Bool
forall k a b c.
Ord k =>
(a -> b -> c) -> Map k a -> Map k b -> Map k c
M.intersectionWith Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
(==) Map a Bool
solution Map a Bool
choices
    isComplete :: Bool
isComplete = Map a Bool -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and Map a Bool
answers Bool -> Bool -> Bool
&& Map a Bool -> Int
forall a. Map a a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length Map a Bool
answers Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= TargetedCorrect -> Int
unTargetedCorrect TargetedCorrect
targeted
    exhaustivenessCheck :: Map Language String -> LangM m
exhaustivenessCheck Map Language String
things = Bool -> LangM m -> LangM m
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
isCorrect
      (LangM m -> LangM m) -> LangM m -> LangM m
forall a b. (a -> b) -> a -> b
$ Bool -> LangM m -> LangM m
forall (m :: * -> *). OutputCapable m => Bool -> LangM m -> LangM m
yesNo Bool
isComplete (LangM m -> LangM m) -> LangM m -> LangM m
forall a b. (a -> b) -> a -> b
$ [(Language, String)] -> LangM m
forall (m :: * -> *).
OutputCapable m =>
[(Language, String)] -> LangM m
multiLang [
      (Language
English, String
"The indicated " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Language -> Map Language String -> String
localise Language
English Map Language String
things String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" are exhaustive?"),
      (Language
German, String
"Die angegebenen " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Language -> Map Language String -> String
localise Language
German Map Language String
things String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" sind vollzählig?")
      ]

{-|
Calculates points based on the portion of correct choices.

Note that invalid entries within the submission list
(i.e. which are not covered by the possible answers map)
are punished like wrong answers.

The following preconditions need to hold before calling this function
but are not checked:

 * targeted correct is at least one
   and not larger than the amount of possible answers
-}
gradeMultipleChoice
  :: Ord k
  => Punishment
  -- ^ how many points to subtract per wrong answer given
  -> TargetedCorrect
  -- ^ how many of all possible correct answers are considered exhaustive
  -> Map k Bool
  -- ^ possible answers and if they are correct
  -> Map k Bool
  -- ^ submission
  -> Rational
gradeMultipleChoice :: forall k.
Ord k =>
Punishment
-> TargetedCorrect -> Map k Bool -> Map k Bool -> Rational
gradeMultipleChoice Punishment {Rational
unPunishment :: Punishment -> Rational
unPunishment :: Rational
..} TargetedCorrect {Int
unTargetedCorrect :: TargetedCorrect -> Int
unTargetedCorrect :: Int
..} Map k Bool
solution Map k Bool
choices =
  Rational -> Rational -> Rational
forall a. Ord a => a -> a -> a
max Rational
0
    (Rational -> Rational) -> Rational -> Rational
forall a b. (a -> b) -> a -> b
$ Rational -> Rational -> Rational
forall a. Ord a => a -> a -> a
min Rational
1 (Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Map k Bool -> Int
forall a. Map k a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length Map k Bool
correct) Integer -> Integer -> Rational
forall a. Integral a => a -> a -> Ratio a
% Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
unTargetedCorrect)
    Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
- Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Map k Bool -> Int
forall a. Map k a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length Map k Bool
incorrect) Integer -> Integer -> Rational
forall a. Integral a => a -> a -> Ratio a
% Integer
1 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
unPunishment
  where
    (Map k Bool
correct, Map k Bool
incorrect) =
      (k -> Bool -> Bool) -> Map k Bool -> (Map k Bool, Map k Bool)
forall k a. (k -> a -> Bool) -> Map k a -> (Map k a, Map k a)
M.partitionWithKey (\k
k -> (Maybe Bool -> Maybe Bool -> Bool
forall a. Eq a => a -> a -> Bool
== k -> Map k Bool -> Maybe Bool
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup k
k Map k Bool
solution) (Maybe Bool -> Bool) -> (Bool -> Maybe Bool) -> Bool -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Maybe Bool
forall a. a -> Maybe a
Just) Map k Bool
choices


{-|
Use the specified article.
-}
data ArticleToUse
  = DefiniteArticle
  -- ^ use definite article(s)
  | IndefiniteArticle
  -- ^ use indefinite article(s)
  deriving (Typeable ArticleToUse
Typeable ArticleToUse =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> ArticleToUse -> c ArticleToUse)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c ArticleToUse)
-> (ArticleToUse -> Constr)
-> (ArticleToUse -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c ArticleToUse))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c ArticleToUse))
-> ((forall b. Data b => b -> b) -> ArticleToUse -> ArticleToUse)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> ArticleToUse -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> ArticleToUse -> r)
-> (forall u. (forall d. Data d => d -> u) -> ArticleToUse -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> ArticleToUse -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> ArticleToUse -> m ArticleToUse)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ArticleToUse -> m ArticleToUse)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ArticleToUse -> m ArticleToUse)
-> Data ArticleToUse
ArticleToUse -> Constr
ArticleToUse -> DataType
(forall b. Data b => b -> b) -> ArticleToUse -> ArticleToUse
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> ArticleToUse -> u
forall u. (forall d. Data d => d -> u) -> ArticleToUse -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ArticleToUse -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ArticleToUse -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ArticleToUse -> m ArticleToUse
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ArticleToUse -> m ArticleToUse
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ArticleToUse
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ArticleToUse -> c ArticleToUse
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ArticleToUse)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c ArticleToUse)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ArticleToUse -> c ArticleToUse
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ArticleToUse -> c ArticleToUse
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ArticleToUse
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ArticleToUse
$ctoConstr :: ArticleToUse -> Constr
toConstr :: ArticleToUse -> Constr
$cdataTypeOf :: ArticleToUse -> DataType
dataTypeOf :: ArticleToUse -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ArticleToUse)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ArticleToUse)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c ArticleToUse)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c ArticleToUse)
$cgmapT :: (forall b. Data b => b -> b) -> ArticleToUse -> ArticleToUse
gmapT :: (forall b. Data b => b -> b) -> ArticleToUse -> ArticleToUse
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ArticleToUse -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ArticleToUse -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ArticleToUse -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ArticleToUse -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> ArticleToUse -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> ArticleToUse -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ArticleToUse -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ArticleToUse -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ArticleToUse -> m ArticleToUse
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ArticleToUse -> m ArticleToUse
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ArticleToUse -> m ArticleToUse
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ArticleToUse -> m ArticleToUse
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ArticleToUse -> m ArticleToUse
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ArticleToUse -> m ArticleToUse
Data, ArticleToUse -> ArticleToUse -> Bool
(ArticleToUse -> ArticleToUse -> Bool)
-> (ArticleToUse -> ArticleToUse -> Bool) -> Eq ArticleToUse
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ArticleToUse -> ArticleToUse -> Bool
== :: ArticleToUse -> ArticleToUse -> Bool
$c/= :: ArticleToUse -> ArticleToUse -> Bool
/= :: ArticleToUse -> ArticleToUse -> Bool
Eq, (forall x. ArticleToUse -> Rep ArticleToUse x)
-> (forall x. Rep ArticleToUse x -> ArticleToUse)
-> Generic ArticleToUse
forall x. Rep ArticleToUse x -> ArticleToUse
forall x. ArticleToUse -> Rep ArticleToUse x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ArticleToUse -> Rep ArticleToUse x
from :: forall x. ArticleToUse -> Rep ArticleToUse x
$cto :: forall x. Rep ArticleToUse x -> ArticleToUse
to :: forall x. Rep ArticleToUse x -> ArticleToUse
Generic, Eq ArticleToUse
Eq ArticleToUse =>
(Int -> ArticleToUse -> Int)
-> (ArticleToUse -> Int) -> Hashable ArticleToUse
Int -> ArticleToUse -> Int
ArticleToUse -> Int
forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> ArticleToUse -> Int
hashWithSalt :: Int -> ArticleToUse -> Int
$chash :: ArticleToUse -> Int
hash :: ArticleToUse -> Int
Hashable, ReadPrec [ArticleToUse]
ReadPrec ArticleToUse
Int -> ReadS ArticleToUse
ReadS [ArticleToUse]
(Int -> ReadS ArticleToUse)
-> ReadS [ArticleToUse]
-> ReadPrec ArticleToUse
-> ReadPrec [ArticleToUse]
-> Read ArticleToUse
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS ArticleToUse
readsPrec :: Int -> ReadS ArticleToUse
$creadList :: ReadS [ArticleToUse]
readList :: ReadS [ArticleToUse]
$creadPrec :: ReadPrec ArticleToUse
readPrec :: ReadPrec ArticleToUse
$creadListPrec :: ReadPrec [ArticleToUse]
readListPrec :: ReadPrec [ArticleToUse]
Read, Parser [ArticleToUse]
Parser ArticleToUse
Int -> Parser ArticleToUse
Parser ArticleToUse
-> (Int -> Parser ArticleToUse)
-> Parser ArticleToUse
-> (Int -> Parser ArticleToUse)
-> Parser [ArticleToUse]
-> Reader ArticleToUse
forall a.
Parser a
-> (Int -> Parser a)
-> Parser a
-> (Int -> Parser a)
-> Parser [a]
-> Reader a
$catomic_reader :: Parser ArticleToUse
atomic_reader :: Parser ArticleToUse
$catomic_readerPrec :: Int -> Parser ArticleToUse
atomic_readerPrec :: Int -> Parser ArticleToUse
$creader :: Parser ArticleToUse
reader :: Parser ArticleToUse
$creaderPrec :: Int -> Parser ArticleToUse
readerPrec :: Int -> Parser ArticleToUse
$creaderList :: Parser [ArticleToUse]
readerList :: Parser [ArticleToUse]
Reader, Int -> ArticleToUse -> String -> String
[ArticleToUse] -> String -> String
ArticleToUse -> String
(Int -> ArticleToUse -> String -> String)
-> (ArticleToUse -> String)
-> ([ArticleToUse] -> String -> String)
-> Show ArticleToUse
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> ArticleToUse -> String -> String
showsPrec :: Int -> ArticleToUse -> String -> String
$cshow :: ArticleToUse -> String
show :: ArticleToUse -> String
$cshowList :: [ArticleToUse] -> String -> String
showList :: [ArticleToUse] -> String -> String
Show, Int -> ArticleToUse -> Doc
[ArticleToUse] -> Doc
(Int -> ArticleToUse -> Doc)
-> ([ArticleToUse] -> Doc) -> ToDoc ArticleToUse
forall a. (Int -> a -> Doc) -> ([a] -> Doc) -> ToDoc a
$ctoDocPrec :: Int -> ArticleToUse -> Doc
toDocPrec :: Int -> ArticleToUse -> Doc
$ctoDocList :: [ArticleToUse] -> Doc
toDocList :: [ArticleToUse] -> Doc
ToDoc)

{-|
Outputs the correct solution (if given)
when achieved points are less than 100 percent.
No points are distributed if not at least 50 percent are achieved.
(see 'printSolutionAndAssertWithMinimum')
-}
printSolutionAndAssert
  :: OutputCapable m
  => Bool
  -- ^ whether to mention exhaustiveness
  -- (use "correct and exhaustive" instead of just "correct" in output text)
  -> Maybe (ArticleToUse, String)
  -- ^ the correct solution to show,
  -- and the article kind indicating if multiple different solutions could be possible
  -> Rational
  -- ^ points achieved
  -> Rated m
printSolutionAndAssert :: forall (m :: * -> *).
OutputCapable m =>
Bool -> Maybe (ArticleToUse, String) -> Rational -> Rated m
printSolutionAndAssert = MinimumThreshold
-> Bool -> Maybe (ArticleToUse, String) -> Rational -> Rated m
forall (m :: * -> *).
OutputCapable m =>
MinimumThreshold
-> Bool -> Maybe (ArticleToUse, String) -> Rational -> Rated m
printSolutionAndAssertWithMinimum
  (MinimumThreshold
 -> Bool -> Maybe (ArticleToUse, String) -> Rational -> Rated m)
-> MinimumThreshold
-> Bool
-> Maybe (ArticleToUse, String)
-> Rational
-> Rated m
forall a b. (a -> b) -> a -> b
$ Rational -> MinimumThreshold
MinimumThreshold (Integer
1 Integer -> Integer -> Rational
forall a. Integral a => a -> a -> Ratio a
% Integer
2)

{-|
Outputs the correct solution (if given)
when achieved points are less than 100 percent.
No points are distributed if they do not reach the minimum threshold.
-}
printSolutionAndAssertWithMinimum
  :: OutputCapable m
  => MinimumThreshold
  -- ^ the minimum threshold of achieved points
  -> Bool
  -- ^ whether to mention exhaustiveness
  -- (use "correct and exhaustive" instead of just "correct" in output text)
  -> Maybe (ArticleToUse, String)
  -- ^ the correct solution to show,
  -- and the article kind indicating if multiple different solutions could be possible
  -> Rational
  -- ^ points achieved
  -> Rated m
printSolutionAndAssertWithMinimum :: forall (m :: * -> *).
OutputCapable m =>
MinimumThreshold
-> Bool -> Maybe (ArticleToUse, String) -> Rational -> Rated m
printSolutionAndAssertWithMinimum
  MinimumThreshold
minimumPoints
  Bool
mentionExhaustiveness
  Maybe (ArticleToUse, String)
optionalSolution
  Rational
points
  = do
  Maybe (ArticleToUse, String)
-> ((ArticleToUse, String) -> GenericLangM Language m ())
-> GenericLangM Language m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ Maybe (ArticleToUse, String)
optionalSolution (\(ArticleToUse
articleToUse, String
solutionString) ->
    Bool -> GenericLangM Language m () -> GenericLangM Language m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Rational
points Rational -> Rational -> Bool
forall a. Eq a => a -> a -> Bool
/= Rational
1) (GenericLangM Language m () -> GenericLangM Language m ())
-> GenericLangM Language m () -> GenericLangM Language m ()
forall a b. (a -> b) -> a -> b
$ GenericLangM Language m () -> GenericLangM Language m ()
forall l (m :: * -> *).
GenericOutputCapable l m =>
GenericLangM l m () -> GenericLangM l m ()
paragraph (GenericLangM Language m () -> GenericLangM Language m ())
-> GenericLangM Language m () -> GenericLangM Language m ()
forall a b. (a -> b) -> a -> b
$ do
      State (Map Language String) () -> GenericLangM Language m ()
forall l (m :: * -> *).
GenericOutputCapable l m =>
State (Map l String) () -> GenericLangM l m ()
translate (State (Map Language String) () -> GenericLangM Language m ())
-> State (Map Language String) () -> GenericLangM Language m ()
forall a b. (a -> b) -> a -> b
$ case ArticleToUse
articleToUse of
        ArticleToUse
DefiniteArticle -> do
          String -> State (Map Language String) ()
english (String -> State (Map Language String) ())
-> String -> State (Map Language String) ()
forall a b. (a -> b) -> a -> b
$ if Bool
mentionExhaustiveness
            then String
"The correct and exhaustive solution is:"
            else String
"The correct solution is:"
          String -> State (Map Language String) ()
german (String -> State (Map Language String) ())
-> String -> State (Map Language String) ()
forall a b. (a -> b) -> a -> b
$ if Bool
mentionExhaustiveness
            then String
"Die korrekte und vollzählige Lösung ist:"
            else String
"Die korrekte Lösung ist:"
        ArticleToUse
IndefiniteArticle -> do
          String -> State (Map Language String) ()
english (String -> State (Map Language String) ())
-> String -> State (Map Language String) ()
forall a b. (a -> b) -> a -> b
$ if Bool
mentionExhaustiveness
            then String
"A correct and exhaustive solution is:"
            else String
"A correct solution is:"
          String -> State (Map Language String) ()
german (String -> State (Map Language String) ())
-> String -> State (Map Language String) ()
forall a b. (a -> b) -> a -> b
$ if Bool
mentionExhaustiveness
            then String
"Eine korrekte und vollzählige Lösung ist:"
            else String
"Eine korrekte Lösung ist:"
      String -> GenericLangM Language m ()
forall l (m :: * -> *).
GenericOutputCapable l m =>
String -> GenericLangM l m ()
code String
solutionString
      pure ()
    )
  Bool -> GenericLangM Language m () -> GenericLangM Language m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Rational
points Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
>= MinimumThreshold -> Rational
unMinimumThreshold MinimumThreshold
minimumPoints) (GenericLangM Language m () -> GenericLangM Language m ())
-> GenericLangM Language m () -> GenericLangM Language m ()
forall a b. (a -> b) -> a -> b
$ GenericLangM Language m () -> GenericLangM Language m ()
forall l (m :: * -> *).
GenericOutputCapable l m =>
GenericLangM l m () -> GenericLangM l m ()
refuse (GenericLangM Language m () -> GenericLangM Language m ())
-> GenericLangM Language m () -> GenericLangM Language m ()
forall a b. (a -> b) -> a -> b
$ () -> GenericLangM Language m ()
forall a. a -> GenericLangM Language m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
  return Rational
points

{-|
Outputs feedback on syntax of a single choice submission.
Depending on chosen parameters it might reject the submission.
-}
singleChoiceSyntax
  :: (OutputCapable m, Eq a, Show a)
  => Bool
  -- ^ whether to continue after check (i.e. do not reject wrong answers)
  -> [a]
  -- ^ possible answers
  -> a
  -- ^ the submission to evaluate
  -> LangM m
singleChoiceSyntax :: forall (m :: * -> *) a.
(OutputCapable m, Eq a, Show a) =>
Bool -> [a] -> a -> LangM m
singleChoiceSyntax Bool
withSolution [a]
options a
choice =
  let assert :: Bool -> LangM m -> LangM m
assert = Bool -> Bool -> LangM m -> LangM m
forall (m :: * -> *).
OutputCapable m =>
Bool -> Bool -> LangM m -> LangM m
continueOrAbort Bool
withSolution
  in Bool -> LangM m -> LangM m
assert (a
choice a -> [a] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [a]
options) (LangM m -> LangM m) -> LangM m -> LangM m
forall a b. (a -> b) -> a -> b
$ State (Map Language String) () -> LangM m
forall l (m :: * -> *).
GenericOutputCapable l m =>
State (Map l String) () -> GenericLangM l m ()
translate (State (Map Language String) () -> LangM m)
-> State (Map Language String) () -> LangM m
forall a b. (a -> b) -> a -> b
$ do
    let c :: String
c = a -> String
forall a. Show a => a -> String
show a
choice
    String -> State (Map Language String) ()
english (String -> State (Map Language String) ())
-> String -> State (Map Language String) ()
forall a b. (a -> b) -> a -> b
$ String
"Chosen option " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
c  String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" is available?"
    String -> State (Map Language String) ()
german (String -> State (Map Language String) ())
-> String -> State (Map Language String) ()
forall a b. (a -> b) -> a -> b
$ String
"Gewählte Option " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
c String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" ist verfügbar?"

{-|
Outputs feedback and rates a single choice submission.
-}
singleChoice
  :: (OutputCapable m, Eq a)
  => Map Language String
  -- ^ what is asked for
  -> Maybe (ArticleToUse, String)
  -- ^ the correct solution to show,
  -- and the article kind indicating if multiple different solutions could be possible
  -> a
  -- ^ the correct answer
  -> a
  -- ^ the submission to evaluate
  -> LangM m
singleChoice :: forall (m :: * -> *) a.
(OutputCapable m, Eq a) =>
Map Language String
-> Maybe (ArticleToUse, String) -> a -> a -> LangM m
singleChoice Map Language String
what Maybe (ArticleToUse, String)
optionalSolution a
solution a
choice = GenericLangM Language m Rational -> GenericLangM Language m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (GenericLangM Language m Rational -> GenericLangM Language m ())
-> GenericLangM Language m Rational -> GenericLangM Language m ()
forall a b. (a -> b) -> a -> b
$
  GenericLangM Language m ()
checkCorrect
  GenericLangM Language m ()
-> GenericLangM Language m Rational
-> GenericLangM Language m Rational
forall a b.
GenericLangM Language m a
-> GenericLangM Language m b -> GenericLangM Language m b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Bool
-> Maybe (ArticleToUse, String)
-> Rational
-> GenericLangM Language m Rational
forall (m :: * -> *).
OutputCapable m =>
Bool -> Maybe (ArticleToUse, String) -> Rational -> Rated m
printSolutionAndAssert Bool
False Maybe (ArticleToUse, String)
optionalSolution Rational
points
  where
    correct :: Bool
correct = a
solution a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
choice
    points :: Rational
points = if Bool
correct then Rational
1 else Rational
0
    assert :: Bool -> GenericLangM Language m () -> GenericLangM Language m ()
assert = Bool
-> Bool -> GenericLangM Language m () -> GenericLangM Language m ()
forall (m :: * -> *).
OutputCapable m =>
Bool -> Bool -> LangM m -> LangM m
continueOrAbort (Bool
 -> Bool
 -> GenericLangM Language m ()
 -> GenericLangM Language m ())
-> Bool
-> Bool
-> GenericLangM Language m ()
-> GenericLangM Language m ()
forall a b. (a -> b) -> a -> b
$ Maybe (ArticleToUse, String) -> Bool
forall a. Maybe a -> Bool
isJust Maybe (ArticleToUse, String)
optionalSolution
    checkCorrect :: GenericLangM Language m ()
checkCorrect = Bool -> GenericLangM Language m () -> GenericLangM Language m ()
assert Bool
correct (GenericLangM Language m () -> GenericLangM Language m ())
-> GenericLangM Language m () -> GenericLangM Language m ()
forall a b. (a -> b) -> a -> b
$ [(Language, String)] -> GenericLangM Language m ()
forall (m :: * -> *).
OutputCapable m =>
[(Language, String)] -> LangM m
multiLang [
      (Language
English, String
"Chosen " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Language -> Map Language String -> String
localise Language
English Map Language String
what String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" is correct?"),
      (Language
German, String
"Der/die/das gewählte " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Language -> Map Language String -> String
localise Language
German Map Language String
what String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" ist korrekt?")]

{-|
Append some remarks after some rating function.
But re-reject afterwards (if it was rejected by the rating function).
-}
reRefuse
  :: (Alternative m, Monad m, OutputCapable m)
  => Rated m
  -> LangM m
  -> Rated m
reRefuse :: forall (m :: * -> *).
(Alternative m, Monad m, OutputCapable m) =>
Rated m -> LangM m -> Rated m
reRefuse = Rational
-> GenericLangM Language m Rational
-> GenericLangM Language m ()
-> GenericLangM Language m Rational
forall (m :: * -> *) l b a.
(Alternative m, Monad m, GenericOutputCapable l m) =>
b -> GenericLangM l m b -> GenericLangM l m a -> GenericLangM l m b
reRefuseWith Rational
0

{-|
Append some remarks after a potential rejection.
But re-reject afterwards (if it was rejected before).

@since 0.4.0.3
-}
reRefuseLangM
  :: (Alternative m, Monad m, OutputCapable m)
  => LangM m
  -> LangM m
  -> LangM m
reRefuseLangM :: forall (m :: * -> *).
(Alternative m, Monad m, OutputCapable m) =>
LangM m -> LangM m -> LangM m
reRefuseLangM = ()
-> GenericLangM Language m ()
-> GenericLangM Language m ()
-> GenericLangM Language m ()
forall (m :: * -> *) l b a.
(Alternative m, Monad m, GenericOutputCapable l m) =>
b -> GenericLangM l m b -> GenericLangM l m a -> GenericLangM l m b
reRefuseWith ()

{-|
Append some remarks after a potential rejection.
But re-reject afterwards (if it was rejected before).
-}
reRefuseWith :: (Alternative m, Monad m, GenericOutputCapable l m)
  => b
  -> GenericLangM l m b
  -> GenericLangM l m a
  -> GenericLangM l m b
reRefuseWith :: forall (m :: * -> *) l b a.
(Alternative m, Monad m, GenericOutputCapable l m) =>
b -> GenericLangM l m b -> GenericLangM l m a -> GenericLangM l m b
reRefuseWith b
bottom GenericLangM l m b
xs GenericLangM l m a
ys =
  GenericLangM l m b
-> GenericLangM l m b
-> GenericLangM l m (Either (GenericLangM l m b) b)
forall (m :: * -> *) a l b.
Alternative m =>
a -> GenericLangM l m b -> GenericLangM l m (Either a b)
recoverWith (b -> GenericLangM l m b
forall a. a -> GenericLangM l m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure b
bottom) GenericLangM l m b
xs
    GenericLangM l m (Either (GenericLangM l m b) b)
-> (Either (GenericLangM l m b) b -> GenericLangM l m b)
-> GenericLangM l m b
forall (m :: * -> *) l a b.
Monad m =>
GenericLangM l m a
-> (a -> GenericLangM l m b) -> GenericLangM l m b
$>>= \Either (GenericLangM l m b) b
x -> GenericLangM l m a
ys
    GenericLangM l m a -> GenericLangM l m b -> GenericLangM l m b
forall (m :: * -> *) l a b.
Monad m =>
GenericLangM l m a -> GenericLangM l m b -> GenericLangM l m b
$>> (GenericLangM l m b -> GenericLangM l m b)
-> (b -> GenericLangM l m b)
-> Either (GenericLangM l m b) b
-> GenericLangM l m b
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (GenericLangM l m () -> GenericLangM l m ()
forall l (m :: * -> *).
GenericOutputCapable l m =>
GenericLangM l m () -> GenericLangM l m ()
refuse (() -> GenericLangM l m ()
forall a. a -> GenericLangM l m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()) GenericLangM l m () -> GenericLangM l m b -> GenericLangM l m b
forall a b.
GenericLangM l m a -> GenericLangM l m b -> GenericLangM l m b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*>) b -> GenericLangM l m b
forall a. a -> GenericLangM l m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Either (GenericLangM l m b) b
x

multiLang :: OutputCapable m => [(Language, String)] -> LangM m
multiLang :: forall (m :: * -> *).
OutputCapable m =>
[(Language, String)] -> LangM m
multiLang [(Language, String)]
xs = (Language -> String) -> GenericLangM Language m ()
forall l (m :: * -> *).
GenericOutputCapable l m =>
(l -> String) -> GenericLangM l m ()
translated ((Language -> String) -> GenericLangM Language m ())
-> (Language -> String) -> GenericLangM Language m ()
forall a b. (a -> b) -> a -> b
$ \Language
l ->
  String -> Maybe String -> String
forall a. a -> Maybe a -> a
fromMaybe String
"" (Maybe String -> String) -> Maybe String -> String
forall a b. (a -> b) -> a -> b
$ Language -> [(Language, String)] -> Maybe String
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Language
l [(Language, String)]
xs

localise :: Language -> Map Language String -> String
localise :: Language -> Map Language String -> String
localise Language
l Map Language String
lm = String -> Maybe String -> String
forall a. a -> Maybe a -> a
fromMaybe String
nonExistent (Maybe String -> String) -> Maybe String -> String
forall a b. (a -> b) -> a -> b
$ Language -> Map Language String -> Maybe String
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup Language
l Map Language String
lm
  where
    nonExistent :: String
nonExistent
      | Map Language String -> Bool
forall a. Map Language a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null Map Language String
lm   = String -> String
forall a. HasCallStack => String -> a
error String
"missing translation"
      | Bool
otherwise = (Language, String) -> String
forall a b. (a, b) -> b
snd ((Language, String) -> String) -> (Language, String) -> String
forall a b. (a -> b) -> a -> b
$ Map Language String -> (Language, String)
forall k a. Map k a -> (k, a)
M.findMin Map Language String
lm

{-|
This is a more specific version of 'Generic.translate'
which enforces the usage pattern.
You should always prefer this version over the generic.
-}
translate
  :: GenericOutputCapable l m
  => State (Map l String) ()
  -> GenericLangM l m ()
translate :: forall l (m :: * -> *).
GenericOutputCapable l m =>
State (Map l String) () -> GenericLangM l m ()
translate = State (Map l String) () -> GenericLangM l m ()
forall language (m :: * -> *) a.
GenericOutputCapable language m =>
State (Map language String) a -> GenericLangM language m ()
Generic.translate

{-|
This is a more specific version of 'Generic.translateCode'
which enforces the usage pattern.
You should always prefer this version over the generic.
-}
translateCode
  :: GenericOutputCapable l m
  => State (Map l String) ()
  -> GenericLangM l m ()
translateCode :: forall l (m :: * -> *).
GenericOutputCapable l m =>
State (Map l String) () -> GenericLangM l m ()
translateCode = State (Map l String) () -> GenericLangM l m ()
forall language (m :: * -> *) a.
GenericOutputCapable language m =>
State (Map language String) a -> GenericLangM language m ()
Generic.translateCode

{-|
This is a more specific version of 'Generic.translations'
which enforces the usage pattern.
You should always prefer this version over the generic.
-}
translations :: State (Map l a) () -> Map l a
translations :: forall l a. State (Map l a) () -> Map l a
translations = State (Map l a) () -> Map l a
forall language a1 a2.
State (Map language a1) a2 -> Map language a1
Generic.translations

{-|
This is a more specific version of 'Generic.collapsed'
which enforces the usage pattern.
You should always prefer this version over the generic.
-}
collapsed
  :: GenericOutputCapable l m
  => Bool
  -> Map l String
  -> GenericLangM l m ()
  -> GenericLangM l m ()
collapsed :: forall l (m :: * -> *).
GenericOutputCapable l m =>
Bool -> Map l String -> GenericLangM l m () -> GenericLangM l m ()
collapsed = Bool -> Map l String -> GenericLangM l m () -> GenericLangM l m ()
forall l (m :: * -> *).
GenericOutputCapable l m =>
Bool -> Map l String -> GenericLangM l m () -> GenericLangM l m ()
Generic.collapsed

{-|
Provide an English translation
to be appended after previous English translations.
-}
english :: String -> State (Map Language String) ()
english :: String -> State (Map Language String) ()
english = (Map Language String -> Map Language String)
-> State (Map Language String) ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((Map Language String -> Map Language String)
 -> State (Map Language String) ())
-> (String -> Map Language String -> Map Language String)
-> String
-> State (Map Language String) ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> String -> String)
-> Language -> String -> Map Language String -> Map Language String
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
M.insertWith ((String -> String -> String) -> String -> String -> String
forall a b c. (a -> b -> c) -> b -> a -> c
flip String -> String -> String
forall a. [a] -> [a] -> [a]
(++)) Language
English

{-|
Provide an German translation
to be appended after previous German translations.
-}
german :: String -> State (Map Language String) ()
german :: String -> State (Map Language String) ()
german = (Map Language String -> Map Language String)
-> State (Map Language String) ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((Map Language String -> Map Language String)
 -> State (Map Language String) ())
-> (String -> Map Language String -> Map Language String)
-> String
-> State (Map Language String) ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> String -> String)
-> Language -> String -> Map Language String -> Map Language String
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
M.insertWith ((String -> String -> String) -> String -> String -> String
forall a b c. (a -> b -> c) -> b -> a -> c
flip String -> String -> String
forall a. [a] -> [a] -> [a]
(++)) Language
German

type LangM' m a = GenericLangM Language m a
type LangM m = LangM' m ()
type Rated m = LangM' m Rational

enumerate
  :: GenericOutputCapable l m
  => (k -> String)
  -> (a -> String)
  -> Map k a
  -> GenericLangM l m ()
enumerate :: forall l (m :: * -> *) k a.
GenericOutputCapable l m =>
(k -> String) -> (a -> String) -> Map k a -> GenericLangM l m ()
enumerate k -> String
f a -> String
g Map k a
m = (k -> GenericLangM l m ())
-> [(k, GenericLangM l m ())] -> GenericLangM l m ()
forall a.
(a -> GenericLangM l m ())
-> [(a, GenericLangM l m ())] -> GenericLangM l m ()
forall l (m :: * -> *) a.
GenericOutputCapable l m =>
(a -> GenericLangM l m ())
-> [(a, GenericLangM l m ())] -> GenericLangM l m ()
enumerateM (String -> GenericLangM l m ()
forall l (m :: * -> *).
GenericOutputCapable l m =>
String -> GenericLangM l m ()
text (String -> GenericLangM l m ())
-> (k -> String) -> k -> GenericLangM l m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. k -> String
f) (Map k (GenericLangM l m ()) -> [(k, GenericLangM l m ())]
forall k a. Map k a -> [(k, a)]
M.toList (Map k (GenericLangM l m ()) -> [(k, GenericLangM l m ())])
-> Map k (GenericLangM l m ()) -> [(k, GenericLangM l m ())]
forall a b. (a -> b) -> a -> b
$ String -> GenericLangM l m ()
forall l (m :: * -> *).
GenericOutputCapable l m =>
String -> GenericLangM l m ()
text (String -> GenericLangM l m ())
-> (a -> String) -> a -> GenericLangM l m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
g (a -> GenericLangM l m ())
-> Map k a -> Map k (GenericLangM l m ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map k a
m)

type OutputCapable m = GenericOutputCapable Language m

out :: Monad m => GenericOut l o -> GenericLangM l (GenericReportT l o m) ()
out :: forall (m :: * -> *) l o.
Monad m =>
GenericOut l o -> GenericLangM l (GenericReportT l o m) ()
out = GenericReportT l o m () -> GenericLangM l (GenericReportT l o m) ()
forall (f :: * -> *) a. Functor f => f a -> GenericLangM l f a
forall (t :: (* -> *) -> * -> *) (f :: * -> *) a.
(FunctorTrans t, Functor f) =>
f a -> t f a
lift (GenericReportT l o m ()
 -> GenericLangM l (GenericReportT l o m) ())
-> (GenericOut l o -> GenericReportT l o m ())
-> GenericOut l o
-> GenericLangM l (GenericReportT l o m) ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MaybeT (WriterT [GenericOut l o] m) () -> GenericReportT l o m ()
forall l o (m :: * -> *) r.
MaybeT (WriterT [GenericOut l o] m) r -> GenericReportT l o m r
Report (MaybeT (WriterT [GenericOut l o] m) () -> GenericReportT l o m ())
-> (GenericOut l o -> MaybeT (WriterT [GenericOut l o] m) ())
-> GenericOut l o
-> GenericReportT l o m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [GenericOut l o] -> MaybeT (WriterT [GenericOut l o] m) ()
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell ([GenericOut l o] -> MaybeT (WriterT [GenericOut l o] m) ())
-> (GenericOut l o -> [GenericOut l o])
-> GenericOut l o
-> MaybeT (WriterT [GenericOut l o] m) ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (GenericOut l o -> [GenericOut l o] -> [GenericOut l o]
forall a. a -> [a] -> [a]
:[])

instance (l ~ Language)
  => GenericOutputCapable l (GenericReportT l (IO ()) IO)
  where
  assertion :: Bool
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
assertion Bool
p GenericLangM l (GenericReportT l (IO ()) IO) ()
m = (if Bool
p then GenericLangM l (GenericReportT l (IO ()) IO) ()
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall a. a -> a
id else GenericLangM l (GenericReportT l (IO ()) IO) ()
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall l (m :: * -> *).
GenericOutputCapable l m =>
GenericLangM l m () -> GenericLangM l m ()
refuse)
    (GenericLangM l (GenericReportT l (IO ()) IO) ()
 -> GenericLangM l (GenericReportT l (IO ()) IO) ())
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall a b. (a -> b) -> a -> b
$ Bool
-> LangM (GenericReportT l (IO ()) IO)
-> LangM (GenericReportT l (IO ()) IO)
forall (m :: * -> *). OutputCapable m => Bool -> LangM m -> LangM m
yesNo Bool
p GenericLangM l (GenericReportT l (IO ()) IO) ()
LangM (GenericReportT l (IO ()) IO)
m
  image :: String -> GenericLangM l (GenericReportT l (IO ()) IO) ()
image         = IO () -> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall (m :: * -> *) o l.
Monad m =>
o -> GenericLangM l (GenericReportT l o m) ()
format (IO () -> GenericLangM l (GenericReportT l (IO ()) IO) ())
-> (String -> IO ())
-> String
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> IO ()
putStr (String -> IO ()) -> (String -> String) -> String -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String
"file: " String -> String -> String
forall a. [a] -> [a] -> [a]
++)
  images :: forall k a.
(k -> String)
-> (a -> String)
-> Map k a
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
images k -> String
g a -> String
f    = IO () -> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall (m :: * -> *) o l.
Monad m =>
o -> GenericLangM l (GenericReportT l o m) ()
format (IO () -> GenericLangM l (GenericReportT l (IO ()) IO) ())
-> (Map k a -> IO ())
-> Map k a
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> IO ()
putStrLn (String -> IO ()) -> (Map k a -> String) -> Map k a -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (k -> a -> String -> String) -> String -> Map k a -> String
forall k a b. (k -> a -> b -> b) -> b -> Map k a -> b
foldrWithKey
    (\k
k a
x String
rs -> k -> String
g k
k String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
". file: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
f a
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ Char
'\n' Char -> String -> String
forall a. a -> [a] -> [a]
: String
rs)
    String
""
  paragraph :: GenericLangM l (GenericReportT l (IO ()) IO) ()
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
paragraph     = (GenericLangM l (GenericReportT l (IO ()) IO) ()
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall a b.
GenericLangM l (GenericReportT l (IO ()) IO) a
-> GenericLangM l (GenericReportT l (IO ()) IO) b
-> GenericLangM l (GenericReportT l (IO ()) IO) b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> IO () -> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall (m :: * -> *) o l.
Monad m =>
o -> GenericLangM l (GenericReportT l o m) ()
format (String -> IO ()
putStrLn String
""))
  text :: String -> GenericLangM l (GenericReportT l (IO ()) IO) ()
text          = IO () -> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall (m :: * -> *) o l.
Monad m =>
o -> GenericLangM l (GenericReportT l o m) ()
format (IO () -> GenericLangM l (GenericReportT l (IO ()) IO) ())
-> (String -> IO ())
-> String
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> IO ()
putStr
  enumerateM :: forall a.
(a -> GenericLangM l (GenericReportT l (IO ()) IO) ())
-> [(a, GenericLangM l (GenericReportT l (IO ()) IO) ())]
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
enumerateM a -> GenericLangM l (GenericReportT l (IO ()) IO) ()
p  = (GenericLangM l (GenericReportT l (IO ()) IO) ()
 -> (a, GenericLangM l (GenericReportT l (IO ()) IO) ())
 -> GenericLangM l (GenericReportT l (IO ()) IO) ())
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
-> [(a, GenericLangM l (GenericReportT l (IO ()) IO) ())]
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl
    (\GenericLangM l (GenericReportT l (IO ()) IO) ()
o (a
x, GenericLangM l (GenericReportT l (IO ()) IO) ()
e) -> GenericLangM l (GenericReportT l (IO ()) IO) ()
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall l (m :: * -> *).
GenericOutputCapable l m =>
GenericLangM l m () -> GenericLangM l m ()
paragraph (GenericLangM l (GenericReportT l (IO ()) IO) ()
 -> GenericLangM l (GenericReportT l (IO ()) IO) ())
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall a b. (a -> b) -> a -> b
$ do GenericLangM l (GenericReportT l (IO ()) IO) ()
o; a -> GenericLangM l (GenericReportT l (IO ()) IO) ()
p a
x; IO () -> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall (m :: * -> *) o l.
Monad m =>
o -> GenericLangM l (GenericReportT l o m) ()
format (IO () -> GenericLangM l (GenericReportT l (IO ()) IO) ())
-> IO () -> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall a b. (a -> b) -> a -> b
$ String -> IO ()
putStr String
"  "; GenericLangM l (GenericReportT l (IO ()) IO) ()
e; pure ())
    (() -> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall a. a -> GenericLangM l (GenericReportT l (IO ()) IO) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ())
  itemizeM :: [GenericLangM l (GenericReportT l (IO ()) IO) ()]
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
itemizeM      = (GenericLangM l (GenericReportT l (IO ()) IO) ()
 -> GenericLangM l (GenericReportT l (IO ()) IO) ()
 -> GenericLangM l (GenericReportT l (IO ()) IO) ())
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
-> [GenericLangM l (GenericReportT l (IO ()) IO) ()]
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl
    (\GenericLangM l (GenericReportT l (IO ()) IO) ()
o GenericLangM l (GenericReportT l (IO ()) IO) ()
x -> GenericLangM l (GenericReportT l (IO ()) IO) ()
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall l (m :: * -> *).
GenericOutputCapable l m =>
GenericLangM l m () -> GenericLangM l m ()
paragraph (GenericLangM l (GenericReportT l (IO ()) IO) ()
 -> GenericLangM l (GenericReportT l (IO ()) IO) ())
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall a b. (a -> b) -> a -> b
$ do GenericLangM l (GenericReportT l (IO ()) IO) ()
o; IO () -> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall (m :: * -> *) o l.
Monad m =>
o -> GenericLangM l (GenericReportT l o m) ()
format (IO () -> GenericLangM l (GenericReportT l (IO ()) IO) ())
-> IO () -> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall a b. (a -> b) -> a -> b
$ String -> IO ()
putStr String
" -  "; GenericLangM l (GenericReportT l (IO ()) IO) ()
x; pure ())
    (() -> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall a. a -> GenericLangM l (GenericReportT l (IO ()) IO) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ())
  indent :: GenericLangM l (GenericReportT l (IO ()) IO) ()
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
indent GenericLangM l (GenericReportT l (IO ()) IO) ()
xs     = do
    IO () -> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall (m :: * -> *) o l.
Monad m =>
o -> GenericLangM l (GenericReportT l o m) ()
format (IO () -> GenericLangM l (GenericReportT l (IO ()) IO) ())
-> IO () -> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall a b. (a -> b) -> a -> b
$ String -> IO ()
putStr String
">>>>"
    GenericLangM l (GenericReportT l (IO ()) IO) ()
xs
    IO () -> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall (m :: * -> *) o l.
Monad m =>
o -> GenericLangM l (GenericReportT l o m) ()
format (IO () -> GenericLangM l (GenericReportT l (IO ()) IO) ())
-> IO () -> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall a b. (a -> b) -> a -> b
$ String -> IO ()
putStrLn String
"<<<<"
    pure ()
  refuse :: GenericLangM l (GenericReportT l (IO ()) IO) ()
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
refuse        = GenericLangM l (GenericReportT l (IO ()) IO) ()
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall (m :: * -> *) l o.
Monad m =>
GenericLangM l (GenericReportT l o m) ()
-> GenericLangM l (GenericReportT l o m) ()
toAbort
  latex :: String -> GenericLangM l (GenericReportT l (IO ()) IO) ()
latex         = IO () -> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall (m :: * -> *) o l.
Monad m =>
o -> GenericLangM l (GenericReportT l o m) ()
format (IO () -> GenericLangM l (GenericReportT l (IO ()) IO) ())
-> (String -> IO ())
-> String
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> IO ()
putStrLn (String -> IO ()) -> (String -> String) -> String -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String
"LaTeX: " String -> String -> String
forall a. [a] -> [a] -> [a]
++)
  folded :: Bool
-> (l -> String)
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
folded Bool
b l -> String
t GenericLangM l (GenericReportT l (IO ()) IO) ()
c = do
    IO () -> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall (m :: * -> *) o l.
Monad m =>
o -> GenericLangM l (GenericReportT l o m) ()
format (IO () -> GenericLangM l (GenericReportT l (IO ()) IO) ())
-> IO () -> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall a b. (a -> b) -> a -> b
$ String -> IO ()
putStr (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"(" String -> String -> String
forall a. [a] -> [a] -> [a]
++ (if Bool
b then String
"+" else String
"-") String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
") "
    (l -> String) -> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall l (m :: * -> *).
GenericOutputCapable l m =>
(l -> String) -> GenericLangM l m ()
translated l -> String
t
    IO () -> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall (m :: * -> *) o l.
Monad m =>
o -> GenericLangM l (GenericReportT l o m) ()
format (IO () -> GenericLangM l (GenericReportT l (IO ()) IO) ())
-> IO () -> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall a b. (a -> b) -> a -> b
$ String -> IO ()
putStrLn String
""
    Bool
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
b (GenericLangM l (GenericReportT l (IO ()) IO) ()
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall l (m :: * -> *).
GenericOutputCapable l m =>
GenericLangM l m () -> GenericLangM l m ()
indent GenericLangM l (GenericReportT l (IO ()) IO) ()
c)
    pure ()
  code :: String -> GenericLangM l (GenericReportT l (IO ()) IO) ()
code          = IO () -> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall (m :: * -> *) o l.
Monad m =>
o -> GenericLangM l (GenericReportT l o m) ()
format (IO () -> GenericLangM l (GenericReportT l (IO ()) IO) ())
-> (String -> IO ())
-> String
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> IO ()
putStr (String -> IO ()) -> (String -> String) -> String -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\String
xs -> String
" <" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
xs String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"> ")
  translatedCode :: (l -> String) -> GenericLangM l (GenericReportT l (IO ()) IO) ()
translatedCode l -> String
lm =
    GenericOut l (IO ())
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall (m :: * -> *) l o.
Monad m =>
GenericOut l o -> GenericLangM l (GenericReportT l o m) ()
out ((l -> IO ()) -> GenericOut l (IO ())
forall l o. (l -> o) -> GenericOut l o
Localised ((l -> IO ()) -> GenericOut l (IO ()))
-> (l -> IO ()) -> GenericOut l (IO ())
forall a b. (a -> b) -> a -> b
$ String -> IO ()
putStr (String -> IO ()) -> (l -> String) -> l -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\String
xs -> String
" <" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
xs String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"> ") (String -> String) -> (l -> String) -> l -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. l -> String
lm)
  translated :: (l -> String) -> GenericLangM l (GenericReportT l (IO ()) IO) ()
translated l -> String
lm = GenericOut l (IO ())
-> GenericLangM l (GenericReportT l (IO ()) IO) ()
forall (m :: * -> *) l o.
Monad m =>
GenericOut l o -> GenericLangM l (GenericReportT l o m) ()
out ((l -> IO ()) -> GenericOut l (IO ())
forall l o. (l -> o) -> GenericOut l o
Localised ((l -> IO ()) -> GenericOut l (IO ()))
-> (l -> IO ()) -> GenericOut l (IO ())
forall a b. (a -> b) -> a -> b
$ String -> IO ()
putStr (String -> IO ()) -> (l -> String) -> l -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. l -> String
lm)

instance l ~ Language
  => RunnableOutputCapable l (GenericReportT l (IO ()) IO)
  where
  type RunMonad l (GenericReportT l (IO ()) IO) = IO
  type Output l (GenericReportT l (IO ()) IO) = IO ()
  runLangM :: forall a.
GenericLangM l (GenericReportT l (IO ()) IO) a
-> RunMonad
     l
     (GenericReportT l (IO ()) IO)
     (Maybe a, l -> Output l (GenericReportT l (IO ()) IO))
runLangM = IO ()
-> (IO () -> IO () -> IO ())
-> GenericLangM l (GenericReportT l (IO ()) IO) a
-> IO (Maybe a, l -> IO ())
forall (m :: * -> *) o l a.
Functor m =>
o
-> (o -> o -> o)
-> GenericLangM l (GenericReportT l o m) a
-> m (Maybe a, l -> o)
runLangMReport (() -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()) IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
(>>)

{-|
This is a more specific version of 'Generic.combineReports'
which enforces the usage pattern.
You should always prefer this version over the generic.
-}
combineReports
  :: Monad m
  => ([[o]] -> o)
  -> [GenericLangM l (GenericReportT l o m) ()]
  -> GenericLangM l (GenericReportT l o m) ()
combineReports :: forall (m :: * -> *) o l.
Monad m =>
([[o]] -> o)
-> [GenericLangM l (GenericReportT l o m) ()]
-> GenericLangM l (GenericReportT l o m) ()
combineReports = ([[o]] -> o)
-> [GenericLangM l (GenericReportT l o m) ()]
-> GenericLangM l (GenericReportT l o m) ()
forall (m :: * -> *) o l a.
Monad m =>
([[o]] -> o)
-> [GenericLangM l (GenericReportT l o m) a]
-> GenericLangM l (GenericReportT l o m) ()
Generic.combineReports

{-|
This is a more specific version of 'Generic.alignOutput'
which enforces the usage pattern.
You should always prefer this version over the generic.
-}
alignOutput
  :: Monad m
  => ([o] -> o)
  -> GenericLangM l (GenericReportT l o m) ()
  -> GenericLangM l (GenericReportT l o m) ()
alignOutput :: forall (m :: * -> *) o l.
Monad m =>
([o] -> o)
-> GenericLangM l (GenericReportT l o m) ()
-> GenericLangM l (GenericReportT l o m) ()
alignOutput = ([o] -> o)
-> GenericLangM l (GenericReportT l o m) ()
-> GenericLangM l (GenericReportT l o m) ()
forall (m :: * -> *) o l a.
Monad m =>
([o] -> o)
-> GenericLangM l (GenericReportT l o m) a
-> GenericLangM l (GenericReportT l o m) ()
Generic.alignOutput

{-|
This is a more specific version of 'Generic.combineTwoReports'
which enforces the usage pattern.
You should always prefer this version over the generic.
-}
combineTwoReports
  :: Monad m
  => ([o] -> [o] -> o)
  -> GenericLangM l (GenericReportT l o m) ()
  -> GenericLangM l (GenericReportT l o m) ()
  -> GenericLangM l (GenericReportT l o m) ()
combineTwoReports :: forall (m :: * -> *) o l.
Monad m =>
([o] -> [o] -> o)
-> GenericLangM l (GenericReportT l o m) ()
-> GenericLangM l (GenericReportT l o m) ()
-> GenericLangM l (GenericReportT l o m) ()
combineTwoReports = ([o] -> [o] -> o)
-> GenericLangM l (GenericReportT l o m) ()
-> GenericLangM l (GenericReportT l o m) ()
-> GenericLangM l (GenericReportT l o m) ()
forall (m :: * -> *) o l a b.
Monad m =>
([o] -> [o] -> o)
-> GenericLangM l (GenericReportT l o m) a
-> GenericLangM l (GenericReportT l o m) b
-> GenericLangM l (GenericReportT l o m) ()
Generic.combineTwoReports

{-|
This is a more specific version of 'Generic.toAbort'
which enforces the usage pattern.
You should always prefer this version over the generic.
-}
toAbort
  :: Monad m
  => GenericLangM l (GenericReportT l o m) ()
  -> GenericLangM l (GenericReportT l o m) ()
toAbort :: forall (m :: * -> *) l o.
Monad m =>
GenericLangM l (GenericReportT l o m) ()
-> GenericLangM l (GenericReportT l o m) ()
toAbort = GenericLangM l (GenericReportT l o m) ()
-> GenericLangM l (GenericReportT l o m) ()
forall (m :: * -> *) l o a b.
Monad m =>
GenericLangM l (GenericReportT l o m) a
-> GenericLangM l (GenericReportT l o m) b
Generic.toAbort

-- | Configuration options for additional text
data ExtraText
  = NoExtraText
  -- ^ Provide no additional text.
  | Static
  -- ^ Provide additional text that is always shown.
      !(Map Language String)
      -- ^ The text do be displayed.
  | Collapsible
  -- ^ Provide additional text that can be collapsed.
      !Bool
      -- ^ The default collapse status of the text.
      !(Map Language String)
      -- ^ The description of the text to be shown.
      !(Map Language String)
      -- ^ The text to be shown when not collapsed.
  deriving (Typeable ExtraText
Typeable ExtraText =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> ExtraText -> c ExtraText)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c ExtraText)
-> (ExtraText -> Constr)
-> (ExtraText -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c ExtraText))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ExtraText))
-> ((forall b. Data b => b -> b) -> ExtraText -> ExtraText)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> ExtraText -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> ExtraText -> r)
-> (forall u. (forall d. Data d => d -> u) -> ExtraText -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> ExtraText -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> ExtraText -> m ExtraText)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ExtraText -> m ExtraText)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ExtraText -> m ExtraText)
-> Data ExtraText
ExtraText -> Constr
ExtraText -> DataType
(forall b. Data b => b -> b) -> ExtraText -> ExtraText
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> ExtraText -> u
forall u. (forall d. Data d => d -> u) -> ExtraText -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ExtraText -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ExtraText -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ExtraText -> m ExtraText
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ExtraText -> m ExtraText
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ExtraText
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ExtraText -> c ExtraText
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ExtraText)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ExtraText)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ExtraText -> c ExtraText
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ExtraText -> c ExtraText
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ExtraText
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ExtraText
$ctoConstr :: ExtraText -> Constr
toConstr :: ExtraText -> Constr
$cdataTypeOf :: ExtraText -> DataType
dataTypeOf :: ExtraText -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ExtraText)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ExtraText)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ExtraText)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ExtraText)
$cgmapT :: (forall b. Data b => b -> b) -> ExtraText -> ExtraText
gmapT :: (forall b. Data b => b -> b) -> ExtraText -> ExtraText
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ExtraText -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ExtraText -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ExtraText -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ExtraText -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> ExtraText -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> ExtraText -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ExtraText -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ExtraText -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ExtraText -> m ExtraText
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ExtraText -> m ExtraText
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ExtraText -> m ExtraText
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ExtraText -> m ExtraText
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ExtraText -> m ExtraText
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ExtraText -> m ExtraText
Data, ExtraText -> ExtraText -> Bool
(ExtraText -> ExtraText -> Bool)
-> (ExtraText -> ExtraText -> Bool) -> Eq ExtraText
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ExtraText -> ExtraText -> Bool
== :: ExtraText -> ExtraText -> Bool
$c/= :: ExtraText -> ExtraText -> Bool
/= :: ExtraText -> ExtraText -> Bool
Eq, (forall x. ExtraText -> Rep ExtraText x)
-> (forall x. Rep ExtraText x -> ExtraText) -> Generic ExtraText
forall x. Rep ExtraText x -> ExtraText
forall x. ExtraText -> Rep ExtraText x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ExtraText -> Rep ExtraText x
from :: forall x. ExtraText -> Rep ExtraText x
$cto :: forall x. Rep ExtraText x -> ExtraText
to :: forall x. Rep ExtraText x -> ExtraText
Generic, Eq ExtraText
Eq ExtraText =>
(Int -> ExtraText -> Int)
-> (ExtraText -> Int) -> Hashable ExtraText
Int -> ExtraText -> Int
ExtraText -> Int
forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> ExtraText -> Int
hashWithSalt :: Int -> ExtraText -> Int
$chash :: ExtraText -> Int
hash :: ExtraText -> Int
Hashable, ReadPrec [ExtraText]
ReadPrec ExtraText
Int -> ReadS ExtraText
ReadS [ExtraText]
(Int -> ReadS ExtraText)
-> ReadS [ExtraText]
-> ReadPrec ExtraText
-> ReadPrec [ExtraText]
-> Read ExtraText
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS ExtraText
readsPrec :: Int -> ReadS ExtraText
$creadList :: ReadS [ExtraText]
readList :: ReadS [ExtraText]
$creadPrec :: ReadPrec ExtraText
readPrec :: ReadPrec ExtraText
$creadListPrec :: ReadPrec [ExtraText]
readListPrec :: ReadPrec [ExtraText]
Read, Parser [ExtraText]
Parser ExtraText
Int -> Parser ExtraText
Parser ExtraText
-> (Int -> Parser ExtraText)
-> Parser ExtraText
-> (Int -> Parser ExtraText)
-> Parser [ExtraText]
-> Reader ExtraText
forall a.
Parser a
-> (Int -> Parser a)
-> Parser a
-> (Int -> Parser a)
-> Parser [a]
-> Reader a
$catomic_reader :: Parser ExtraText
atomic_reader :: Parser ExtraText
$catomic_readerPrec :: Int -> Parser ExtraText
atomic_readerPrec :: Int -> Parser ExtraText
$creader :: Parser ExtraText
reader :: Parser ExtraText
$creaderPrec :: Int -> Parser ExtraText
readerPrec :: Int -> Parser ExtraText
$creaderList :: Parser [ExtraText]
readerList :: Parser [ExtraText]
Reader, Int -> ExtraText -> String -> String
[ExtraText] -> String -> String
ExtraText -> String
(Int -> ExtraText -> String -> String)
-> (ExtraText -> String)
-> ([ExtraText] -> String -> String)
-> Show ExtraText
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> ExtraText -> String -> String
showsPrec :: Int -> ExtraText -> String -> String
$cshow :: ExtraText -> String
show :: ExtraText -> String
$cshowList :: [ExtraText] -> String -> String
showList :: [ExtraText] -> String -> String
Show, Int -> ExtraText -> Doc
[ExtraText] -> Doc
(Int -> ExtraText -> Doc)
-> ([ExtraText] -> Doc) -> ToDoc ExtraText
forall a. (Int -> a -> Doc) -> ([a] -> Doc) -> ToDoc a
$ctoDocPrec :: Int -> ExtraText -> Doc
toDocPrec :: Int -> ExtraText -> Doc
$ctoDocList :: [ExtraText] -> Doc
toDocList :: [ExtraText] -> Doc
ToDoc)

{-|
Render extra text as paragraph.
-}
extra :: OutputCapable m => ExtraText -> LangM m
extra :: forall (m :: * -> *). OutputCapable m => ExtraText -> LangM m
extra ExtraText
NoExtraText = () -> GenericLangM Language m ()
forall a. a -> GenericLangM Language m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
extra (Static Map Language String
textMap) = GenericLangM Language m () -> GenericLangM Language m ()
forall l (m :: * -> *).
GenericOutputCapable l m =>
GenericLangM l m () -> GenericLangM l m ()
paragraph (GenericLangM Language m () -> GenericLangM Language m ())
-> GenericLangM Language m () -> GenericLangM Language m ()
forall a b. (a -> b) -> a -> b
$ State (Map Language String) () -> GenericLangM Language m ()
forall l (m :: * -> *).
GenericOutputCapable l m =>
State (Map l String) () -> GenericLangM l m ()
translate (State (Map Language String) () -> GenericLangM Language m ())
-> State (Map Language String) () -> GenericLangM Language m ()
forall a b. (a -> b) -> a -> b
$ Map Language String -> State (Map Language String) ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put Map Language String
textMap
extra (Collapsible Bool
defaultState Map Language String
titleText Map Language String
contentText) =
  Bool
-> Map Language String
-> GenericLangM Language m ()
-> GenericLangM Language m ()
forall l (m :: * -> *).
GenericOutputCapable l m =>
Bool -> Map l String -> GenericLangM l m () -> GenericLangM l m ()
collapsed
    Bool
defaultState
    Map Language String
titleText
    (State (Map Language String) () -> GenericLangM Language m ()
forall l (m :: * -> *).
GenericOutputCapable l m =>
State (Map l String) () -> GenericLangM l m ()
translate (State (Map Language String) () -> GenericLangM Language m ())
-> State (Map Language String) () -> GenericLangM Language m ()
forall a b. (a -> b) -> a -> b
$ Map Language String -> State (Map Language String) ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put Map Language String
contentText)