summaryrefslogtreecommitdiff
path: root/src/Sequence
diff options
context:
space:
mode:
authorGregor Kleen <gkleen@yggdrasil.li>2016-06-08 22:45:07 +0200
committerGregor Kleen <gkleen@yggdrasil.li>2016-06-08 22:45:07 +0200
commit85486c4838e23ca6d8b643c759d4e2a3035ef61d (patch)
treeca642cb38eae17ba88002c97973d79a9f34bf457 /src/Sequence
parent73c24db325e741ca9402152d934bd28c7ac89fed (diff)
download2017-01-16_17:13:37-85486c4838e23ca6d8b643c759d4e2a3035ef61d.tar
2017-01-16_17:13:37-85486c4838e23ca6d8b643c759d4e2a3035ef61d.tar.gz
2017-01-16_17:13:37-85486c4838e23ca6d8b643c759d4e2a3035ef61d.tar.bz2
2017-01-16_17:13:37-85486c4838e23ca6d8b643c759d4e2a3035ef61d.tar.xz
2017-01-16_17:13:37-85486c4838e23ca6d8b643c759d4e2a3035ef61d.zip
framework for damage tracking
Diffstat (limited to 'src/Sequence')
-rw-r--r--src/Sequence/Contact/Archetypes.hs29
-rw-r--r--src/Sequence/Contact/Tests.hs32
-rw-r--r--src/Sequence/Contact/Types.hs218
-rw-r--r--src/Sequence/Contact/Types/Internal.hs200
-rw-r--r--src/Sequence/Formula.hs25
5 files changed, 372 insertions, 132 deletions
diff --git a/src/Sequence/Contact/Archetypes.hs b/src/Sequence/Contact/Archetypes.hs
index 193892a..3e9b416 100644
--- a/src/Sequence/Contact/Archetypes.hs
+++ b/src/Sequence/Contact/Archetypes.hs
@@ -85,6 +85,17 @@ human = Humanoid
85 , _sSeqVal = vReflexes * 2 + vMobility + vPerception + d 10 85 , _sSeqVal = vReflexes * 2 + vMobility + vPerception + d 10
86 , _sPainTolerance = vMass `quot'` 2 + vWillpower 86 , _sPainTolerance = vMass `quot'` 2 + vWillpower
87 , _sFatigueTolerance = vWillpower `quot'` 2 + vEndurance 87 , _sFatigueTolerance = vWillpower `quot'` 2 + vEndurance
88
89 , _sHitzones = [ ("Kopf", 0.05)
90 , ("Torso", 0.49)
91 , ("Rechter Arm", 0.08)
92 , ("Linker Arm", 0.08)
93 , ("Unterleib", 0.10)
94 , ("Rechtes Bein", 0.10)
95 , ("Linkes Bein", 0.10)
96 ]
97 , _sDamage = const 0
98 , _sArmor = const def
88 } 99 }
89 100
90dog = Quadruped 101dog = Quadruped
@@ -109,6 +120,17 @@ dog = Quadruped
109 , _sSeqVal = vReflexes * 2 + vMobility + vPerception + 2 * d 10 120 , _sSeqVal = vReflexes * 2 + vMobility + vPerception + 2 * d 10
110 , _sPainTolerance = vMass `quot'` 2 + vWillpower 121 , _sPainTolerance = vMass `quot'` 2 + vWillpower
111 , _sFatigueTolerance = vWillpower `quot'` 2 + vEndurance 122 , _sFatigueTolerance = vWillpower `quot'` 2 + vEndurance
123
124 , _sHitzones = [ ("Kopf", 0.05)
125 , ("Torso", 0.49)
126 , ("Rechter Vorderlauf", 0.08)
127 , ("Linker Vorderlauf", 0.08)
128 , ("Hinterteil", 0.10)
129 , ("Rechter Hinterlauf", 0.10)
130 , ("Linker Hinterlauf", 0.10)
131 ]
132 , _sDamage = const 0
133 , _sArmor = const def
112 } 134 }
113 135
114dolphin = Dolphin 136dolphin = Dolphin
@@ -133,6 +155,13 @@ dolphin = Dolphin
133 , _sSeqVal = vReflexes * 2 + vMobility + vPerception + 2 * d 10 155 , _sSeqVal = vReflexes * 2 + vMobility + vPerception + 2 * d 10
134 , _sPainTolerance = vMass `quot'` 2 + vWillpower 156 , _sPainTolerance = vMass `quot'` 2 + vWillpower
135 , _sFatigueTolerance = vWillpower `quot'` 2 + vEndurance 157 , _sFatigueTolerance = vWillpower `quot'` 2 + vEndurance
158
159 , _sHitzones = [ ("Kopf", 0.10)
160 , ("Rumpf", 0.65)
161 , ("Schwanz", 0.25)
162 ]
163 , _sDamage = const 0
164 , _sArmor = const def
136 } 165 }
137 166
138childOfMu = human 167childOfMu = human
diff --git a/src/Sequence/Contact/Tests.hs b/src/Sequence/Contact/Tests.hs
index 8aa072a..82b1cf3 100644
--- a/src/Sequence/Contact/Tests.hs
+++ b/src/Sequence/Contact/Tests.hs
@@ -1,9 +1,7 @@
1{-# LANGUAGE TemplateHaskell, OverloadedStrings, OverloadedLists, ViewPatterns, MultiParamTypeClasses, FlexibleContexts, RankNTypes, TypeSynonymInstances, FlexibleInstances, ImpredicativeTypes #-} 1{-# LANGUAGE TemplateHaskell, OverloadedStrings, OverloadedLists, ViewPatterns, MultiParamTypeClasses, FlexibleContexts, RankNTypes, TypeSynonymInstances, FlexibleInstances #-}
2 2
3module Sequence.Contact.Tests 3module Sequence.Contact.Tests
4 ( TestResult(..), rWith, rBy 4 ( enactTest
5 , Test, tCritSuccessMod, tCritFailureMod, tBaseDifficulty, tMod
6 , enactTest
7 ) where 5 ) where
8 6
9import Sequence.Formula 7import Sequence.Formula
@@ -13,6 +11,7 @@ import Sequence.Contact.Types
13 11
14import Control.Monad 12import Control.Monad
15import Control.Monad.Reader 13import Control.Monad.Reader
14import Control.Monad.Base
16import Control.Lens 15import Control.Lens
17 16
18import Data.Default 17import Data.Default
@@ -29,31 +28,6 @@ import Data.Traversable (mapM)
29 28
30import Prelude hiding (mapM) 29import Prelude hiding (mapM)
31 30
32
33data TestResult = CritSuccess { _rWith, _rBy :: Int }
34 | Success { _rWith, _rBy :: Int }
35 | Failure { _rWith, _rBy :: Int }
36 | CritFailure { _rWith, _rBy :: Int }
37 deriving (Eq, Ord, Show)
38makeLenses ''TestResult
39
40data Test = Test
41 { _tCritSuccessMod
42 , _tCritFailureMod
43 , _tBaseDifficulty
44 , _tMod :: Int
45 }
46 deriving (Eq, Ord)
47makeLenses ''Test
48
49instance Default Test where
50 def = Test
51 { _tCritSuccessMod = 0
52 , _tCritFailureMod = 0
53 , _tBaseDifficulty = 50
54 , _tMod = 0
55 }
56
57tests :: MonadReader Stats m => m (Map (CI String) (FormulaM Stats Test)) 31tests :: MonadReader Stats m => m (Map (CI String) (FormulaM Stats Test))
58tests = mconcat <$> sequence [ test "Stärke" $ sAStrength . attributeTest 32tests = mconcat <$> sequence [ test "Stärke" $ sAStrength . attributeTest
59 33
diff --git a/src/Sequence/Contact/Types.hs b/src/Sequence/Contact/Types.hs
index c00a60d..cd1bc02 100644
--- a/src/Sequence/Contact/Types.hs
+++ b/src/Sequence/Contact/Types.hs
@@ -1,6 +1,9 @@
1{-# LANGUAGE TemplateHaskell, RecordWildCards, OverloadedStrings, OverloadedLists, ViewPatterns, RankNTypes #-} 1{-# LANGUAGE TemplateHaskell, RecordWildCards, OverloadedStrings, OverloadedLists, ViewPatterns, RankNTypes, ImpredicativeTypes #-}
2 2
3module Sequence.Contact.Types where 3module Sequence.Contact.Types
4 ( module Sequence.Contact.Types
5 , module Sequence.Contact.Types.Internal
6 ) where
4 7
5import Sequence.Formula 8import Sequence.Formula
6 9
@@ -9,105 +12,103 @@ import Control.Lens
9 12
10import Data.Default 13import Data.Default
11 14
12data Stats = Prop 15import Data.Map (Map)
13 | Humanoid 16import qualified Data.Map as Map
14 { _sAStrength 17
15 , _sAEndurance 18import Data.CaseInsensitive (CI)
16 , _sAMass 19import qualified Data.CaseInsensitive as CI
17 , _sAReflexes 20
18 , _sAMobility 21import Data.String (IsString(..))
19 , _sADexterity 22import Data.Function (on)
20 , _sAIntelligence 23import Data.Maybe
21 , _sACharisma 24import Data.Ratio
22 , _sAPerception 25
23 , _sAWillpower 26import Control.Monad.Reader (ask)
24 27import Control.Monad.State
25 , _sSArchaicRanged 28
26 , _sSFirearms 29import Sequence.Contact.Types.Internal
27 , _sSHeavyWeapons 30
28 , _sSEnergyWeapons 31hitzone :: Iso' String Hitzone
29 , _sSUnarmedMelee 32hitzone = iso (Hitzone . CI.mk) (CI.original . _hitzone)
30 , _sSArmedMelee 33
31 , _sSThrownWeapons 34instance IsString Hitzone where
32 , _sSStealth 35 fromString = view hitzone
33 , _sSThievery 36
34 , _sSLockpicking 37makeLenses ''Armor
35 , _sSTrapping 38
36 , _sSSciences 39instance Default Armor where
37 , _sSFirstAid 40 def = Armor
38 , _sSMedicine 41 { _aBallistic = 0
39 , _sSHumanities 42 , _aPiercing = 0
40 , _sSEngineering 43 , _aBlunt = 0
41 , _sSCraft 44 , _aHeat = 0
42 , _sSInterface 45 , _aCold = 0
43 , _sSSpeech 46 , _aToxic = 0
44 , _sSLeadership 47 , _aExplosive = 0
45 , _sSHomeEconomics 48 }
46 , _sSSurvival 49
47 , _sSMotorcycle 50makeLenses ''TestResult
48 , _sSWheeled 51
49 , _sSHovercraft 52makeLenses ''Test
50 , _sSAircraft 53
51 , _sSSpacecraft 54instance Default Test where
52 , _sSWatercraft 55 def = Test
53 , _sSTracked 56 { _tName = ""
54 , _sSExoskeleton 57 , _tCritSuccessMod = 0
55 58 , _tCritFailureMod = 0
56 , _sMaxVitality 59 , _tBaseDifficulty = 50
57 , _sSeqVal 60 , _tMod = 0
58 , _sPainTolerance 61 }
59 , _sFatigueTolerance :: Formula Stats 62
60 } 63makePrisms ''Modifier
61 | Quadruped 64
62 { _sAStrength 65instance Eq Modifier where
63 , _sAEndurance 66 (==) = (==) `on` (view $ _Modifier . _1)
64 , _sAMass 67
65 , _sAReflexes 68instance Ord Modifier where
66 , _sAMobility 69 compare = compare `on` (view $ _Modifier . _1)
67 , _sADexterity 70
68 , _sAIntelligence 71instance Default Modifier where
69 , _sACharisma 72 def = Modifier "" pure
70 , _sAPerception 73
71 , _sAWillpower 74makePrisms ''Effect
72 75
73 , _sSBiting 76instance Eq Effect where
74 , _sSSearching 77 (==) = (==) `on` (view $ _Effect . _1)
75 , _sSStealth 78
76 , _sSLeadership 79instance Ord Effect where
77 , _sSDemeanour 80 compare = compare `on` (view $ _Effect . _1)
78 81
79 , _sMaxVitality 82instance Default Effect where
80 , _sSeqVal 83 def = Effect "" pure
81 , _sPainTolerance 84
82 , _sFatigueTolerance :: Formula Stats 85makeLenses ''ShockEffect
83 } 86
84 | Dolphin 87instance Default ShockEffect where
85 { _sAStrength 88 def = ShockEffect { _seApplied = False
86 , _sAEndurance 89 , _seVal = pure Nothing
87 , _sAMass 90 , _seBar = pure Nothing
88 , _sAReflexes 91 , _seEffect = def
89 , _sAMobility 92 }
90 , _sADexterity 93
91 , _sAIntelligence
92 , _sACharisma
93 , _sAPerception
94 , _sAWillpower
95
96 , _sSRamming
97 , _sSTargeting
98 , _sSSearching
99 , _sSStealth
100 , _sSComprehension
101
102 , _sMaxVitality
103 , _sSeqVal
104 , _sPainTolerance
105 , _sFatigueTolerance :: Formula Stats
106 }
107makeLenses ''Stats 94makeLenses ''Stats
108 95
109instance Default Stats where 96instance Default Stats where
110 def = Prop 97 def = Prop
98 { _sHitzones = [("Volumen", 1)]
99 , _sDamage = const 0
100 , _sFatigue = 0
101 , _sCripple = const def
102 , _sArmor = const def
103
104 , _sExtraSkills = []
105 , _sModifiers = []
106 }
107
108applyModifier :: String -> (Test -> FormulaM Stats Test) -> Effect
109applyModifier effectName modifier = Effect (CI.mk effectName) $ return . apply
110 where
111 apply = sModifiers <>~ [Modifier (CI.mk $ effectName ++ " (modifier)") modifier]
111 112
112vStrength = val sAStrength "Stärke?" True 113vStrength = val sAStrength "Stärke?" True
113vEndurance = val sAEndurance "Ausdauer?" True 114vEndurance = val sAEndurance "Ausdauer?" True
@@ -119,3 +120,26 @@ vIntelligence = val sAIntelligence "Intelligenz?" True
119vCharisma = val sACharisma "Charisma?" True 120vCharisma = val sACharisma "Charisma?" True
120vPerception = val sAPerception "Wahrnehmung?" True 121vPerception = val sAPerception "Wahrnehmung?" True
121vWillpower = val sAWillpower "Entschlossenheit?" True 122vWillpower = val sAWillpower "Entschlossenheit?" True
123
124scaled :: (Real a, Fractional a, Integral b) => Ratio b -> Iso' a a
125scaled (realToFrac -> ratio) = iso (* ratio) (/ ratio)
126
127sDamage' :: String -> Traversal' Stats Int
128sDamage' (view hitzone -> zone) = sDamage . ix zone
129
130sCripple' :: String -> Traversal' Stats ShockEffect
131sCripple' (view hitzone -> zone) = sCripple . ix zone
132
133sTotalDamage :: Lens' Stats Int
134sTotalDamage = lens retrieve undefined
135 where
136 retrieve = do
137 hitzones <- Map.keys <$> view sHitzones
138 damageMap <- view sDamage
139 return . sum $ pure damageMap <*> hitzones
140
141sDead :: Fold Stats (FormulaM Stats Bool)
142sDead = folding $ do
143 maxVitality <- preview sMaxVitality
144 damage <- view sTotalDamage
145 return $ liftM2 (>) <$> Just (return damage) <*> maxVitality
diff --git a/src/Sequence/Contact/Types/Internal.hs b/src/Sequence/Contact/Types/Internal.hs
new file mode 100644
index 0000000..9929801
--- /dev/null
+++ b/src/Sequence/Contact/Types/Internal.hs
@@ -0,0 +1,200 @@
1{-# LANGUAGE RankNTypes #-}
2
3module Sequence.Contact.Types.Internal where
4
5import Sequence.Formula (Formula, FormulaM, Table)
6
7import Data.Map (Map)
8import Data.Set (Set)
9import Data.Ratio
10
11import Control.Lens
12
13import Data.CaseInsensitive (CI)
14
15newtype Hitzone = Hitzone { _hitzone :: CI String }
16 deriving (Eq, Ord)
17
18data Armor = Armor
19 { _aBallistic
20 , _aPiercing
21 , _aBlunt
22 , _aHeat
23 , _aCold
24 , _aToxic
25 , _aExplosive :: Int
26 }
27
28data TestResult = CritSuccess { _rWith, _rBy :: Int }
29 | Success { _rWith, _rBy :: Int }
30 | Failure { _rWith, _rBy :: Int }
31 | CritFailure { _rWith, _rBy :: Int }
32 deriving (Eq, Ord, Show)
33
34data Test = Test
35 { _tName :: CI String
36 , _tCritSuccessMod
37 , _tCritFailureMod
38 , _tBaseDifficulty
39 , _tMod :: Int
40 }
41 deriving (Eq, Ord)
42
43data Modifier = Modifier (CI String) (Test -> FormulaM Stats Test)
44
45data Effect = Effect (CI String) (Stats -> FormulaM Stats Stats)
46
47data ShockEffect = ShockEffect
48 { _seApplied :: Bool
49 , _seVal :: FormulaM Stats (Maybe Int)
50 , _seBar :: FormulaM Stats (Maybe Int)
51 , _seEffect :: Table Effect
52 }
53
54data Stats = Prop
55 { _sHitzones :: Table Hitzone
56 , _sArmor :: Hitzone -> Armor
57 , _sCripple :: Hitzone -> ShockEffect
58
59 , _sDamage :: Hitzone -> Int
60 , _sFatigue :: Int
61
62 , _sPainShock :: ShockEffect
63 , _sFatigueShock :: ShockEffect
64
65 , _sExtraSkills :: Map (CI String) (FormulaM Stats Test)
66 , _sModifiers :: Set Modifier
67 }
68 | Humanoid
69 { _sAStrength
70 , _sAEndurance
71 , _sAMass
72 , _sAReflexes
73 , _sAMobility
74 , _sADexterity
75 , _sAIntelligence
76 , _sACharisma
77 , _sAPerception
78 , _sAWillpower
79
80 , _sSArchaicRanged
81 , _sSFirearms
82 , _sSHeavyWeapons
83 , _sSEnergyWeapons
84 , _sSUnarmedMelee
85 , _sSArmedMelee
86 , _sSThrownWeapons
87 , _sSStealth
88 , _sSThievery
89 , _sSLockpicking
90 , _sSTrapping
91 , _sSSciences
92 , _sSFirstAid
93 , _sSMedicine
94 , _sSHumanities
95 , _sSEngineering
96 , _sSCraft
97 , _sSInterface
98 , _sSSpeech
99 , _sSLeadership
100 , _sSHomeEconomics
101 , _sSSurvival
102 , _sSMotorcycle
103 , _sSWheeled
104 , _sSHovercraft
105 , _sSAircraft
106 , _sSSpacecraft
107 , _sSWatercraft
108 , _sSTracked
109 , _sSExoskeleton
110
111 , _sMaxVitality
112 , _sSeqVal
113 , _sPainTolerance
114 , _sFatigueTolerance :: Formula Stats
115
116 , _sHitzones :: Table Hitzone
117 , _sArmor :: Hitzone -> Armor
118 , _sCripple :: Hitzone -> ShockEffect
119
120 , _sDamage :: Hitzone -> Int
121 , _sFatigue :: Int
122
123 , _sPainShock :: ShockEffect
124 , _sFatigueShock :: ShockEffect
125
126 , _sExtraSkills :: Map (CI String) (FormulaM Stats Test)
127 , _sModifiers :: Set Modifier
128 }
129 | Quadruped
130 { _sAStrength
131 , _sAEndurance
132 , _sAMass
133 , _sAReflexes
134 , _sAMobility
135 , _sADexterity
136 , _sAIntelligence
137 , _sACharisma
138 , _sAPerception
139 , _sAWillpower
140
141 , _sSBiting
142 , _sSSearching
143 , _sSStealth
144 , _sSLeadership
145 , _sSDemeanour
146
147 , _sMaxVitality
148 , _sSeqVal
149 , _sPainTolerance
150 , _sFatigueTolerance :: Formula Stats
151
152 , _sHitzones :: Table Hitzone
153 , _sArmor :: Hitzone -> Armor
154 , _sCripple :: Hitzone -> ShockEffect
155
156 , _sDamage :: Hitzone -> Int
157 , _sFatigue :: Int
158
159 , _sPainShock :: ShockEffect
160 , _sFatigueShock :: ShockEffect
161
162 , _sExtraSkills :: Map (CI String) (FormulaM Stats Test)
163 , _sModifiers :: Set Modifier
164 }
165 | Dolphin
166 { _sAStrength
167 , _sAEndurance
168 , _sAMass
169 , _sAReflexes
170 , _sAMobility
171 , _sADexterity
172 , _sAIntelligence
173 , _sACharisma
174 , _sAPerception
175 , _sAWillpower
176
177 , _sSRamming
178 , _sSTargeting
179 , _sSSearching
180 , _sSStealth
181 , _sSComprehension
182
183 , _sMaxVitality
184 , _sSeqVal
185 , _sPainTolerance
186 , _sFatigueTolerance :: Formula Stats
187
188 , _sHitzones :: Table Hitzone
189 , _sArmor :: Hitzone -> Armor
190 , _sCripple :: Hitzone -> ShockEffect
191
192 , _sDamage :: Hitzone -> Int
193 , _sFatigue :: Int
194
195 , _sPainShock :: ShockEffect
196 , _sFatigueShock :: ShockEffect
197
198 , _sExtraSkills :: Map (CI String) (FormulaM Stats Test)
199 , _sModifiers :: Set Modifier
200 }
diff --git a/src/Sequence/Formula.hs b/src/Sequence/Formula.hs
index d486bab..ca945f8 100644
--- a/src/Sequence/Formula.hs
+++ b/src/Sequence/Formula.hs
@@ -2,10 +2,11 @@
2 2
3module Sequence.Formula 3module Sequence.Formula
4 ( FormulaM, Formula, quot' 4 ( FormulaM, Formula, quot'
5 , (:<:)(..), Context(..) 5 , (:<:)(..), Context(..), ctx
6 , evalFormula 6 , evalFormula
7 , val 7 , val
8 , d, z 8 , d, z
9 , Table, table
9 ) where 10 ) where
10 11
11import Control.Lens hiding (Context(..)) 12import Control.Lens hiding (Context(..))
@@ -31,6 +32,9 @@ import Data.Either
31import Data.Set (Set) 32import Data.Set (Set)
32import qualified Data.Set as Set 33import qualified Data.Set as Set
33 34
35import Data.Map (Map)
36import qualified Data.Map as Map
37
34class (:<:) small large where 38class (:<:) small large where
35 ctx' :: Traversal' large small 39 ctx' :: Traversal' large small
36 40
@@ -89,16 +93,20 @@ instance Integral a => Num (FormulaM input a) where
89quot' :: Integral a => FormulaM input a -> FormulaM input a -> FormulaM input a 93quot' :: Integral a => FormulaM input a -> FormulaM input a -> FormulaM input a
90quot' = liftM2 quot 94quot' = liftM2 quot
91 95
92askQuestion :: (MonadIO m, sInput :<: lInput) => lInput -> Question sInput -> m lInput 96askQuestion :: (MonadIO m, sInput :<: lInput) => String -> lInput -> Question sInput -> m lInput
93askQuestion input q@(Question{..}) = flip (set $ ctx' . answer) input . maybe (throwError q) return <$> askQ prompt (join . fmap readMaybe) 97askQuestion promptPref input q@(Question{..}) = flip (set $ ctx' . answer) input . maybe (throwError q) return <$> askQ (promptPref' ++ prompt) (join . fmap readMaybe)
98 where
99 promptPref'
100 | null promptPref = ""
101 | otherwise = promptPref ++ " » "
94 102
95evalFormula :: (MonadIO m, sInput :<: lInput) => lInput -> FormulaM sInput a -> m (lInput, a) 103evalFormula :: (MonadIO m, sInput :<: lInput) => String -> lInput -> FormulaM sInput a -> m (lInput, a)
96evalFormula = evalFormula' [] 104evalFormula = evalFormula' []
97 where 105 where
98 evalFormula' finalChanges input formula = do 106 evalFormula' finalChanges promptPref input formula = do
99 result <- liftIO . enact . runExceptT . (runReaderT ?? (Context input)) . (evalStateT ?? Set.empty) $ formula 107 result <- liftIO . enact . runExceptT . (runReaderT ?? (Context input)) . (evalStateT ?? Set.empty) $ formula
100 case result of 108 case result of
101 Left q@(Question{..}) -> askQuestion input q >>= flip (evalFormula' $ bool (pure . set (ctx' . answer) $ throwError q) mempty keepResult ++ finalChanges) formula 109 Left q@(Question{..}) -> askQuestion promptPref input q >>= flip (flip evalFormula' promptPref $ bool (pure . set (ctx' . answer) $ throwError q) mempty keepResult ++ finalChanges) formula
102 Right result -> return (foldr ($) input finalChanges, result) 110 Right result -> return (foldr ($) input finalChanges, result)
103 111
104val :: Integral a => Traversal' input (Formula input) -> String -> Bool -> Formula input 112val :: Integral a => Traversal' input (Formula input) -> String -> Bool -> Formula input
@@ -109,3 +117,8 @@ val answer prompt keepResult = do
109d, z :: Integral a => Int -> FormulaM input a 117d, z :: Integral a => Int -> FormulaM input a
110d n = liftBase . fmap fromIntegral $ D.d n 118d n = liftBase . fmap fromIntegral $ D.d n
111z n = liftBase . fmap fromIntegral $ D.z n 119z n = liftBase . fmap fromIntegral $ D.z n
120
121type Table a = Map a Rational
122
123table :: Ord a => Table a -> FormulaM input a
124table = liftBase . makeEventProb . Map.assocs