summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Main.hs1
-rw-r--r--src/Sequence/Formula.hs46
-rw-r--r--src/Sequence/Types.hs2
-rw-r--r--src/Sequence/Utils.hs4
4 files changed, 50 insertions, 3 deletions
diff --git a/src/Main.hs b/src/Main.hs
index 96e3fef..8f955bb 100644
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -33,6 +33,7 @@ import Control.Monad.State.Strict
33 33
34import Sequence.Types 34import Sequence.Types
35import Sequence.Utils 35import Sequence.Utils
36import Sequence.Formula
36 37
37import Text.Layout.Table 38import Text.Layout.Table
38 39
diff --git a/src/Sequence/Formula.hs b/src/Sequence/Formula.hs
new file mode 100644
index 0000000..7a6e689
--- /dev/null
+++ b/src/Sequence/Formula.hs
@@ -0,0 +1,46 @@
1{-# LANGUAGE RecordWildCards, RankNTypes, TypeSynonymInstances, FlexibleInstances #-}
2
3module Sequence.Formula
4 ( FormulaM
5 , evalFormula
6 , val
7 ) where
8
9import Control.Lens
10
11import Control.Monad.Trans.Either
12import Control.Monad.Reader
13import Numeric.Probability.Game.Event
14
15import Sequence.Utils
16
17import Text.Read (readMaybe)
18
19type FormulaM input a = ReaderT input (EitherT (Question input) EventM) a
20
21data Question input = Question
22 { answer :: Lens' input (Maybe Int)
23 , prompt :: String
24 }
25
26instance Integral a => Num (FormulaM input a) where
27 (+) x y = (+) <$> x <*> y
28 (-) x y = (-) <$> x <*> y
29 negate = fmap negate
30 abs = fmap abs
31 signum = fmap signum
32 (*) x y = sum <$> (flip replicateM y =<< fromIntegral <$> x)
33 fromInteger = return . fromInteger
34
35askQuestion :: MonadIO m => input -> (Question input) -> m input
36askQuestion input q@(Question{..}) = flip (set answer) input <$> askQ prompt (join . fmap readMaybe)
37
38evalFormula :: MonadIO m => input -> FormulaM input a -> m a
39evalFormula input formula = do
40 result <- liftIO . enact . runEitherT . (runReaderT ?? input) $ formula
41 case result of
42 Left q -> askQuestion input q >>= flip evalFormula formula
43 Right result -> return result
44
45val :: Integral a => Lens' input (Maybe Int) -> String -> FormulaM input Int
46val answer prompt = view answer >>= maybe (lift . left $ Question{..}) return
diff --git a/src/Sequence/Types.hs b/src/Sequence/Types.hs
index 8895569..55c9013 100644
--- a/src/Sequence/Types.hs
+++ b/src/Sequence/Types.hs
@@ -52,7 +52,7 @@ faction' = lens (CI.original . fromMaybe unaligned . view faction) (\s a -> s {
52 | otherwise = Just str' 52 | otherwise = Just str'
53 53
54 54
55newtype SeqVal = SeqVal { _seqVal :: Integer } 55newtype SeqVal = SeqVal { _seqVal :: Int }
56 deriving (Show, Ord, Eq, Num, Integral, Enum, Real) 56 deriving (Show, Ord, Eq, Num, Integral, Enum, Real)
57makeLenses ''SeqVal 57makeLenses ''SeqVal
58 58
diff --git a/src/Sequence/Utils.hs b/src/Sequence/Utils.hs
index 32f8239..f0a8849 100644
--- a/src/Sequence/Utils.hs
+++ b/src/Sequence/Utils.hs
@@ -49,7 +49,7 @@ withFocus f = use gFocus >>= \focus -> case focus of
49 Nothing -> shellPutErrLn $ "Currently not focusing any entity" 49 Nothing -> shellPutErrLn $ "Currently not focusing any entity"
50 Just id -> f id 50 Just id -> f id
51 51
52askBool :: String -> Bool -> Sh st Bool 52askBool :: MonadIO m => String -> Bool -> m Bool
53askBool prompt initial = askQ prompt $ fromMaybe initial . join . fmap (eval . CI.mk) 53askBool prompt initial = askQ prompt $ fromMaybe initial . join . fmap (eval . CI.mk)
54 where 54 where
55 eval "yes" = Just True 55 eval "yes" = Just True
@@ -58,7 +58,7 @@ askBool prompt initial = askQ prompt $ fromMaybe initial . join . fmap (eval . C
58 eval "n" = Just False 58 eval "n" = Just False
59 eval _ = Nothing 59 eval _ = Nothing
60 60
61askQ :: String -> (Maybe String -> a) -> Sh st a 61askQ :: MonadIO m => String -> (Maybe String -> a) -> m a
62askQ prompt eval = eval <$> liftIO (readline $ prompt ++ " ") 62askQ prompt eval = eval <$> liftIO (readline $ prompt ++ " ")
63 63
64unaligned = view faction' def 64unaligned = view faction' def