summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregor Kleen <gkleen@yggdrasil.li>2016-06-05 01:35:13 +0200
committerGregor Kleen <gkleen@yggdrasil.li>2016-06-05 01:35:13 +0200
commitbf7b92a4daff86e3853b1005dcd18c94d14ac362 (patch)
treebc3452562f264ee42799c0d74183e294f4b6fe94
parente93892c008759957e4ee567e7e642bd8a0dd9286 (diff)
download2017-01-16_17:13:37-bf7b92a4daff86e3853b1005dcd18c94d14ac362.tar
2017-01-16_17:13:37-bf7b92a4daff86e3853b1005dcd18c94d14ac362.tar.gz
2017-01-16_17:13:37-bf7b92a4daff86e3853b1005dcd18c94d14ac362.tar.bz2
2017-01-16_17:13:37-bf7b92a4daff86e3853b1005dcd18c94d14ac362.tar.xz
2017-01-16_17:13:37-bf7b92a4daff86e3853b1005dcd18c94d14ac362.zip
Prevent infinite recursion (crudely)
-rw-r--r--sequence.cabal1
-rw-r--r--sequence.nix11
-rw-r--r--src/Sequence/Formula.hs23
3 files changed, 22 insertions, 13 deletions
diff --git a/sequence.cabal b/sequence.cabal
index 47f1532..11e3273 100644
--- a/sequence.cabal
+++ b/sequence.cabal
@@ -35,5 +35,6 @@ executable sequence
35 , game-probability 35 , game-probability
36 , readline 36 , readline
37 , transformers 37 , transformers
38 , transformers-base
38 hs-source-dirs: src 39 hs-source-dirs: src
39 default-language: Haskell2010 \ No newline at end of file 40 default-language: Haskell2010 \ No newline at end of file
diff --git a/sequence.nix b/sequence.nix
index dfc6cb4..7b46a9d 100644
--- a/sequence.nix
+++ b/sequence.nix
@@ -1,7 +1,7 @@
1{ mkDerivation, base, bimap, case-insensitive, containers 1{ mkDerivation, base, bimap, case-insensitive, containers
2, data-default, directory, either, filepath, game-probability, lens 2, data-default, directory, filepath, game-probability, lens, mtl
3, mtl, readline, Shellac, Shellac-haskeline, stdenv, table-layout 3, readline, Shellac, Shellac-haskeline, stdenv, table-layout
4, transformers, xdg-basedir 4, transformers, transformers-base, xdg-basedir
5}: 5}:
6mkDerivation { 6mkDerivation {
7 pname = "sequence"; 7 pname = "sequence";
@@ -11,8 +11,9 @@ mkDerivation {
11 isExecutable = true; 11 isExecutable = true;
12 executableHaskellDepends = [ 12 executableHaskellDepends = [
13 base bimap case-insensitive containers data-default directory 13 base bimap case-insensitive containers data-default directory
14 either filepath game-probability lens mtl readline Shellac 14 filepath game-probability lens mtl readline Shellac
15 Shellac-haskeline table-layout transformers xdg-basedir 15 Shellac-haskeline table-layout transformers transformers-base
16 xdg-basedir
16 ]; 17 ];
17 license = stdenv.lib.licenses.mit; 18 license = stdenv.lib.licenses.mit;
18} 19}
diff --git a/src/Sequence/Formula.hs b/src/Sequence/Formula.hs
index c3e9e33..7fb4ccb 100644
--- a/src/Sequence/Formula.hs
+++ b/src/Sequence/Formula.hs
@@ -13,6 +13,8 @@ import Data.Data.Lens
13import Control.Monad 13import Control.Monad
14import Control.Monad.Except 14import Control.Monad.Except
15import Control.Monad.Reader 15import Control.Monad.Reader
16import Control.Monad.State
17import Control.Monad.Base
16import Numeric.Probability.Game.Event 18import Numeric.Probability.Game.Event
17import qualified Numeric.Probability.Game.Dice as D 19import qualified Numeric.Probability.Game.Dice as D
18 20
@@ -25,13 +27,17 @@ import Data.List
25import Data.Maybe 27import Data.Maybe
26import Data.Either 28import Data.Either
27 29
28import Debug.Trace 30import Data.Set (Set)
31import qualified Data.Set as Set
29 32
30 33
31type FormulaM input a = ReaderT input (ExceptT (Question input) EventM) a 34type FormulaM input a = StateT (Set String) (ReaderT input (ExceptT (Question input) EventM)) a
32 35
33type Formula input = FormulaM input Int 36type Formula input = FormulaM input Int
34 37
38instance MonadBase EventM EventM where
39 liftBase = id
40
35data Question input = Question 41data Question input = Question
36 { answer :: Traversal' input (Formula input) 42 { answer :: Traversal' input (Formula input)
37 , prompt :: String 43 , prompt :: String
@@ -66,15 +72,16 @@ askQuestion input q@(Question{..}) = flip (set answer) input . maybe (throwError
66evalFormula :: (MonadIO m, Ord a, Show a) => input -> FormulaM input a -> m (input, a) 72evalFormula :: (MonadIO m, Ord a, Show a) => input -> FormulaM input a -> m (input, a)
67evalFormula = evalFormula' [] 73evalFormula = evalFormula' []
68 where 74 where
69 evalFormula' finalChanges input formula = trace "evalFormula'" $ do 75 evalFormula' finalChanges input formula = do
70 result <- liftIO . enact . traceShowId . runExceptT . (runReaderT ?? input) $ formula 76 result <- liftIO . enact . runExceptT . (runReaderT ?? input) . (evalStateT ?? Set.empty) $ formula
71 liftIO . traceIO $ show (isLeft result, isRight result)
72 case result of 77 case result of
73 Left q@(Question{..}) -> askQuestion input q >>= flip (evalFormula' $ bool (pure . set answer $ throwError q) mempty keepResult ++ finalChanges) formula 78 Left q@(Question{..}) -> askQuestion input q >>= flip (evalFormula' $ bool (pure . set answer $ throwError q) mempty keepResult ++ finalChanges) formula
74 Right result -> return (foldr ($) input finalChanges, result) 79 Right result -> return (foldr ($) input finalChanges, result)
75 80
76val :: Integral a => Traversal' input (Formula input) -> String -> Bool -> Formula input 81val :: Integral a => Traversal' input (Formula input) -> String -> Bool -> Formula input
77val answer prompt keepResult = preview answer >>= maybe (throwError Question{..}) id . trace "val" 82val answer prompt keepResult = do
83 gets (Set.member prompt) >>= bool (modify $ Set.insert prompt) (throwError Question{..})
84 preview answer >>= maybe (throwError Question{..}) id
78 85
79-- viewL :: Lens' lInput sInput -> Prism' (FormulaM sInput a) (FormulaM lInput a) 86-- viewL :: Lens' lInput sInput -> Prism' (FormulaM sInput a) (FormulaM lInput a)
80-- viewL lTrav = iso asL asS 87-- viewL lTrav = iso asL asS
@@ -87,5 +94,5 @@ val answer prompt keepResult = preview answer >>= maybe (throwError Question{..}
87-- val' lTrav sTrav prompt keepResult = preview (lTrav . sTrav . viewL lTrav) >>= maybe (throwError Question{ answer = lTrav . sTrav . viewL lTrav, ..}) id 94-- val' lTrav sTrav prompt keepResult = preview (lTrav . sTrav . viewL lTrav) >>= maybe (throwError Question{ answer = lTrav . sTrav . viewL lTrav, ..}) id
88 95
89d, z :: Integral a => Int -> FormulaM input a 96d, z :: Integral a => Int -> FormulaM input a
90d n = lift . lift . fmap fromIntegral $ D.d n 97d n = liftBase . fmap fromIntegral $ D.d n
91z n = lift . lift . fmap fromIntegral $ D.z n 98z n = liftBase . fmap fromIntegral $ D.z n