diff options
| author | Gregor Kleen <gkleen@yggdrasil.li> | 2016-06-03 13:53:38 +0200 |
|---|---|---|
| committer | Gregor Kleen <gkleen@yggdrasil.li> | 2016-06-03 13:53:38 +0200 |
| commit | a98cd5d87a0c7959146a8ca35aa40f42fc146ad8 (patch) | |
| tree | cb71228df517c0c639eb60042ce2972a80fc814e /src/Sequence/Formula.hs | |
| parent | 20f53cc1cb01b51bfecc3896c69e881dc72e6e05 (diff) | |
| download | 2017-01-16_17:13:37-a98cd5d87a0c7959146a8ca35aa40f42fc146ad8.tar 2017-01-16_17:13:37-a98cd5d87a0c7959146a8ca35aa40f42fc146ad8.tar.gz 2017-01-16_17:13:37-a98cd5d87a0c7959146a8ca35aa40f42fc146ad8.tar.bz2 2017-01-16_17:13:37-a98cd5d87a0c7959146a8ca35aa40f42fc146ad8.tar.xz 2017-01-16_17:13:37-a98cd5d87a0c7959146a8ca35aa40f42fc146ad8.zip | |
probibilistic computations
Diffstat (limited to 'src/Sequence/Formula.hs')
| -rw-r--r-- | src/Sequence/Formula.hs | 46 |
1 files changed, 46 insertions, 0 deletions
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 | |||
| 3 | module Sequence.Formula | ||
| 4 | ( FormulaM | ||
| 5 | , evalFormula | ||
| 6 | , val | ||
| 7 | ) where | ||
| 8 | |||
| 9 | import Control.Lens | ||
| 10 | |||
| 11 | import Control.Monad.Trans.Either | ||
| 12 | import Control.Monad.Reader | ||
| 13 | import Numeric.Probability.Game.Event | ||
| 14 | |||
| 15 | import Sequence.Utils | ||
| 16 | |||
| 17 | import Text.Read (readMaybe) | ||
| 18 | |||
| 19 | type FormulaM input a = ReaderT input (EitherT (Question input) EventM) a | ||
| 20 | |||
| 21 | data Question input = Question | ||
| 22 | { answer :: Lens' input (Maybe Int) | ||
| 23 | , prompt :: String | ||
| 24 | } | ||
| 25 | |||
| 26 | instance 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 | |||
| 35 | askQuestion :: MonadIO m => input -> (Question input) -> m input | ||
| 36 | askQuestion input q@(Question{..}) = flip (set answer) input <$> askQ prompt (join . fmap readMaybe) | ||
| 37 | |||
| 38 | evalFormula :: MonadIO m => input -> FormulaM input a -> m a | ||
| 39 | evalFormula 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 | |||
| 45 | val :: Integral a => Lens' input (Maybe Int) -> String -> FormulaM input Int | ||
| 46 | val answer prompt = view answer >>= maybe (lift . left $ Question{..}) return | ||
