diff options
| author | Gregor Kleen <gkleen@yggdrasil.li> | 2016-06-05 01:35:13 +0200 |
|---|---|---|
| committer | Gregor Kleen <gkleen@yggdrasil.li> | 2016-06-05 01:35:13 +0200 |
| commit | bf7b92a4daff86e3853b1005dcd18c94d14ac362 (patch) | |
| tree | bc3452562f264ee42799c0d74183e294f4b6fe94 | |
| parent | e93892c008759957e4ee567e7e642bd8a0dd9286 (diff) | |
| download | 2017-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.cabal | 1 | ||||
| -rw-r--r-- | sequence.nix | 11 | ||||
| -rw-r--r-- | src/Sequence/Formula.hs | 23 |
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 | }: |
| 6 | mkDerivation { | 6 | mkDerivation { |
| 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 | |||
| 13 | import Control.Monad | 13 | import Control.Monad |
| 14 | import Control.Monad.Except | 14 | import Control.Monad.Except |
| 15 | import Control.Monad.Reader | 15 | import Control.Monad.Reader |
| 16 | import Control.Monad.State | ||
| 17 | import Control.Monad.Base | ||
| 16 | import Numeric.Probability.Game.Event | 18 | import Numeric.Probability.Game.Event |
| 17 | import qualified Numeric.Probability.Game.Dice as D | 19 | import qualified Numeric.Probability.Game.Dice as D |
| 18 | 20 | ||
| @@ -25,13 +27,17 @@ import Data.List | |||
| 25 | import Data.Maybe | 27 | import Data.Maybe |
| 26 | import Data.Either | 28 | import Data.Either |
| 27 | 29 | ||
| 28 | import Debug.Trace | 30 | import Data.Set (Set) |
| 31 | import qualified Data.Set as Set | ||
| 29 | 32 | ||
| 30 | 33 | ||
| 31 | type FormulaM input a = ReaderT input (ExceptT (Question input) EventM) a | 34 | type FormulaM input a = StateT (Set String) (ReaderT input (ExceptT (Question input) EventM)) a |
| 32 | 35 | ||
| 33 | type Formula input = FormulaM input Int | 36 | type Formula input = FormulaM input Int |
| 34 | 37 | ||
| 38 | instance MonadBase EventM EventM where | ||
| 39 | liftBase = id | ||
| 40 | |||
| 35 | data Question input = Question | 41 | data 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 | |||
| 66 | evalFormula :: (MonadIO m, Ord a, Show a) => input -> FormulaM input a -> m (input, a) | 72 | evalFormula :: (MonadIO m, Ord a, Show a) => input -> FormulaM input a -> m (input, a) |
| 67 | evalFormula = evalFormula' [] | 73 | evalFormula = 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 | ||
| 76 | val :: Integral a => Traversal' input (Formula input) -> String -> Bool -> Formula input | 81 | val :: Integral a => Traversal' input (Formula input) -> String -> Bool -> Formula input |
| 77 | val answer prompt keepResult = preview answer >>= maybe (throwError Question{..}) id . trace "val" | 82 | val 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 | ||
| 89 | d, z :: Integral a => Int -> FormulaM input a | 96 | d, z :: Integral a => Int -> FormulaM input a |
| 90 | d n = lift . lift . fmap fromIntegral $ D.d n | 97 | d n = liftBase . fmap fromIntegral $ D.d n |
| 91 | z n = lift . lift . fmap fromIntegral $ D.z n | 98 | z n = liftBase . fmap fromIntegral $ D.z n |
