Skip to content

Commit 13089e1

Browse files
authored
Merge pull request #154 from L0neGamer/experiment-experiments
Massively improve Dice Stats performance
2 parents fd9137a + 92f97b7 commit 13089e1

18 files changed

Lines changed: 635 additions & 322 deletions

cabal.project

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ packages: .
33
source-repository-package
44
type: git
55
location: git@github.com:L0neGamer/haskell-distribution.git
6-
tag: 569d6452e4bffedb2c0d3795885fccdb22a4d29d
6+
tag: 313eb7a280b010fda1e21876da4171503c76516f
77

88
source-repository-package
99
type: git

package.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ executables:
112112
ghc-options:
113113
- -threaded
114114
- -rtsopts
115+
- -Wall
115116
- "\"-with-rtsopts=-Iw10 -N\""
116117
dependencies:
117118
- tablebot
@@ -124,5 +125,15 @@ tests:
124125
- -threaded
125126
- -rtsopts
126127
- -with-rtsopts=-N
128+
- -Wall
127129
dependencies:
128130
- tablebot
131+
- tasty
132+
- tasty-discover
133+
- tasty-hspec
134+
- tasty-hedgehog
135+
- hspec
136+
- hedgehog
137+
- hspec-hedgehog
138+
build-tools:
139+
- tasty-discover:tasty-discover

src/Tablebot/Plugins/Roll/Dice.hs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ module Tablebot.Plugins.Roll.Dice (evalProgram, evalInteger, evalList, ListValue
8383

8484
import Tablebot.Plugins.Roll.Dice.DiceData
8585
( Converter (promote),
86-
Die (Die),
86+
Die (..),
87+
DieOf (..),
8788
Expr,
8889
ListValues (..),
8990
NumBase (Value),
@@ -94,4 +95,4 @@ import Tablebot.Plugins.Roll.Dice.DiceParsing ()
9495

9596
-- | The default expression to evaluate if no expression is given.
9697
defaultRoll :: Expr
97-
defaultRoll = promote (Die (Value 20))
98+
defaultRoll = promote (MkDie (Die (Value 20)))

src/Tablebot/Plugins/Roll/Dice/DiceData.hs

Lines changed: 75 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -23,29 +23,29 @@ import Tablebot.Plugins.Roll.Dice.DiceFunctions (FuncInfo, FuncInfoBase)
2323
-- evaluated `varValue`.
2424
--
2525
-- List variables have to be prefixed with `l_`. This really helps with parsing.
26-
data Var a = Var {varName :: Text, varValue :: a} | VarLazy {varName :: Text, varValue :: a} deriving (Show)
26+
data Var a = Var {varName :: Text, varValue :: a} | VarLazy {varName :: Text, varValue :: a} deriving (Show, Eq)
2727

2828
-- | If the first value is truthy (non-zero or a non-empty list) then return
2929
-- the `thenValue`, else return the `elseValue`.
30-
data If b = If {ifCond :: Expr, thenValue :: b, elseValue :: b} deriving (Show)
30+
data If b = If {ifCond :: Expr, thenValue :: b, elseValue :: b} deriving (Show, Eq)
3131

3232
-- | Either an If or a Var that returns a `b`.
33-
data MiscData b = MiscIf (If b) | MiscVar (Var b) deriving (Show)
33+
data MiscData b = MiscIf (If b) | MiscVar (Var b) deriving (Show, Eq)
3434

3535
-- | An expression is just an Expr or a ListValues with a semicolon on the end.
3636
--
3737
-- When evaluating, VarLazy expressions are handled with a special case - they
3838
-- are not evaluated until the value is first referenced. Otherwise, the value
3939
-- is evaluated as the statement is encountered
40-
data Statement = StatementExpr Expr | StatementListValues ListValues deriving (Show)
40+
data Statement = StatementExpr Expr | StatementListValues ListValues deriving (Show, Eq)
4141

4242
-- | A program is a series of `Statement`s followed by either a `ListValues` or
4343
-- an Expr.
44-
data Program = Program [Statement] (Either ListValues Expr) deriving (Show)
44+
data Program = Program [Statement] (Either ListValues Expr) deriving (Show, Eq)
4545

4646
-- | The value of an argument given to a function.
4747
data ArgValue = AVExpr Expr | AVListValues ListValues
48-
deriving (Show)
48+
deriving (Show, Eq)
4949

5050
-- | The type for list values.
5151
data ListValues
@@ -59,7 +59,7 @@ data ListValues
5959
LVVar Text
6060
| -- | A misc list values expression.
6161
ListValuesMisc (MiscData ListValues)
62-
deriving (Show)
62+
deriving (Show, Eq)
6363

6464
-- | The type for basic list values (that can be used as is for custom dice).
6565
--
@@ -68,13 +68,11 @@ data ListValues
6868
-- expressions. Effectively what this is used for is so that these can be used
6969
-- as dice side values.
7070
data ListValuesBase = LVBParen (Paren ListValues) | LVBList [Expr]
71-
deriving (Show)
71+
deriving (Show, Eq)
7272

7373
-- | The type for a binary operator between one or more `sub` values
74-
data BinOp sub typ where
75-
BinOp :: (Operation typ) => sub -> [(typ, sub)] -> BinOp sub typ
76-
77-
deriving instance (Show sub, Show typ) => Show (BinOp sub typ)
74+
data BinOp sub typ = BinOp sub [(typ, sub)]
75+
deriving (Show, Eq)
7876

7977
-- | Convenience pattern for the empty list.
8078
pattern SingBinOp :: (Operation typ) => sub -> BinOp sub typ
@@ -91,66 +89,83 @@ class Operation a where
9189
--
9290
-- Represents either a misc expression or additive operations between terms.
9391
data Expr = ExprMisc (MiscData Expr) | Expr (BinOp Term ExprType)
94-
deriving (Show)
92+
deriving (Show, Eq)
9593

9694
-- | The type of the additive expression, either addition or subtraction.
9795
data ExprType = Add | Sub
98-
deriving (Show, Eq)
96+
deriving (Show, Eq, Enum, Bounded)
9997

10098
instance Operation ExprType where
10199
getOperation Sub = (-)
102100
getOperation Add = (+)
103101

104102
-- | Represents multiplicative operations between (possible) negations.
105103
newtype Term = Term (BinOp Negation TermType)
106-
deriving (Show)
104+
deriving (Show, Eq)
107105

108106
-- | The type of the additive expression, either addition or subtraction.
109107
data TermType = Multi | Div
110-
deriving (Show, Eq)
108+
deriving (Show, Eq, Enum, Bounded)
111109

112110
instance Operation TermType where
113111
getOperation Multi = (*)
114112
getOperation Div = div
115113

116114
-- | The type representing a possibly negated value.
117115
data Negation = Neg Expo | NoNeg Expo
118-
deriving (Show)
116+
deriving (Show, Eq)
119117

120118
-- | The type representing a value with exponentials.
121119
data Expo = Expo Func Expo | NoExpo Func
122-
deriving (Show)
120+
deriving (Show, Eq)
123121

124122
-- | The type representing a single function application, or a base item.
125123
data Func = Func FuncInfo [ArgValue] | NoFunc Base
126-
deriving (Show)
124+
deriving (Show, Eq)
127125

128126
-- | The type representing an integer value or an expression in brackets.
129127
data NumBase = NBParen (Paren Expr) | Value Integer
130-
deriving (Show)
128+
deriving (Show, Eq)
131129

132130
-- | Container for a parenthesised value.
133131
newtype Paren a = Paren a
134-
deriving (Show)
132+
deriving (Show, Eq)
135133

136134
-- | The type representing a numeric base value value or a dice value.
137135
data Base = NBase NumBase | DiceBase Dice | NumVar Text
138-
deriving (Show)
136+
deriving (Show, Eq)
139137

140138
-- Dice Operations after this point
141139

140+
data Laziness = Lazy | Strict
141+
142142
-- | The type representing a simple N sided die or a custom die, or a lazy one
143143
-- of one of those values.
144-
data Die = Die NumBase | CustomDie ListValuesBase | LazyDie Die deriving (Show)
144+
data DieOf (l :: Laziness) where
145+
Die :: NumBase -> DieOf l
146+
CustomDie :: ListValuesBase -> DieOf l
147+
LazyDie :: DieOf Strict -> DieOf Lazy
148+
149+
deriving instance Show (DieOf l)
150+
151+
deriving instance Eq (DieOf l)
152+
153+
data Die where
154+
MkDie :: DieOf l -> Die
155+
156+
deriving instance Show Die
157+
158+
instance Eq Die where
159+
(==) (MkDie die1) (MkDie die2) = case (die1, die2) of
160+
(Die n1, Die n2) -> n1 == n2
161+
(CustomDie lvb1, CustomDie lvb2) -> lvb1 == lvb2
162+
(LazyDie do1, LazyDie do2) -> do1 == do2
163+
_ -> False
145164

146165
-- | The type representing a number of dice equal to the `Base` value, and
147166
-- possibly some die options.
148-
data Dice = Dice Base Die (Maybe DieOpRecur)
149-
deriving (Show)
150-
151-
-- | The type representing one or more die options.
152-
data DieOpRecur = DieOpRecur DieOpOption (Maybe DieOpRecur)
153-
deriving (Show)
167+
data Dice = Dice NumBase Die [DieOpOption]
168+
deriving (Show, Eq)
154169

155170
-- | Some more advanced ordering options for things like `<=` and `/=`.
156171
data AdvancedOrdering = Not AdvancedOrdering | OrderingId Ordering | And [AdvancedOrdering] | Or [AdvancedOrdering]
@@ -178,30 +193,50 @@ advancedOrderingMapping = (M.fromList lst, M.fromList $ swap <$> lst)
178193

179194
-- | The type representing a die option; a reroll, a keep/drop operation, or
180195
-- lazily performing some other die option.
181-
data DieOpOption
182-
= Reroll {rerollOnce :: Bool, condition :: AdvancedOrdering, limit :: NumBase}
183-
| DieOpOptionKD KeepDrop LowHighWhere
184-
| DieOpOptionLazy DieOpOption
185-
deriving (Show)
196+
data DieOpOptionOf (l :: Laziness) where
197+
Reroll ::
198+
{rerollOnce :: Bool, condition :: AdvancedOrdering, limit :: NumBase} ->
199+
DieOpOptionOf l
200+
DieOpOptionKD :: KeepDrop -> LowHighWhere -> DieOpOptionOf l
201+
DieOpOptionLazy :: DieOpOptionOf Strict -> DieOpOptionOf Lazy
202+
203+
deriving instance Show (DieOpOptionOf l)
204+
205+
deriving instance Eq (DieOpOptionOf l)
206+
207+
data DieOpOption where
208+
MkDieOpOption :: DieOpOptionOf l -> DieOpOption
209+
210+
deriving instance Show DieOpOption
211+
212+
instance Eq DieOpOption where
213+
(==) (MkDieOpOption doo1) (MkDieOpOption doo2) = case (doo1, doo2) of
214+
(Reroll rro1 cond1 lim1, Reroll rro2 cond2 lim2) ->
215+
rro1 == rro2 && cond1 == cond2 && lim1 == lim2
216+
(DieOpOptionKD kd1 lhw1, DieOpOptionKD kd2 lhw2) -> kd1 == kd2 && lhw1 == lhw2
217+
(DieOpOptionLazy dooo1, DieOpOptionLazy dooo2) -> dooo1 == dooo2
218+
_ -> False
219+
220+
data LowHigh = Low | High
221+
deriving (Show, Eq, Enum, Bounded)
186222

187223
-- | A type used to designate how the keep/drop option should work
188-
data LowHighWhere = Low NumBase | High NumBase | Where AdvancedOrdering NumBase deriving (Show)
224+
data LowHighWhere = LH LowHigh NumBase | Where AdvancedOrdering NumBase deriving (Show, Eq)
189225

190226
-- | Utility function to get the integer determining how many values to get
191227
-- given a `LowHighWhere`. If the given value is `Low` or `High`, then Just the
192228
-- NumBase contained is returned. Else, Nothing is returned.
193229
getValueLowHigh :: LowHighWhere -> Maybe NumBase
194-
getValueLowHigh (Low i) = Just i
195-
getValueLowHigh (High i) = Just i
230+
getValueLowHigh (LH _ i) = Just i
196231
getValueLowHigh (Where _ _) = Nothing
197232

198233
-- | Returns whether the given `LowHighWhere` is `Low` or not.
199234
isLow :: LowHighWhere -> Bool
200-
isLow (Low _) = True
235+
isLow (LH Low _) = True
201236
isLow _ = False
202237

203238
-- | Utility value for whether to keep or drop values.
204-
data KeepDrop = Keep | Drop deriving (Show, Eq)
239+
data KeepDrop = Keep | Drop deriving (Show, Eq, Enum, Bounded)
205240

206241
-- | Utility type class for quickly promoting values.
207242
class Converter a b where
@@ -242,7 +277,7 @@ instance Converter Dice Base where
242277
promote = DiceBase
243278

244279
instance Converter Die Base where
245-
promote d = promote $ Dice (promote (1 :: Integer)) d Nothing
280+
promote d = promote $ Dice (promote (1 :: Integer)) d []
246281

247282
instance Converter [Integer] ListValues where
248283
promote = LVBase . LVBList . (promote <$>)

0 commit comments

Comments
 (0)