Skip to content

Instantly share code, notes, and snippets.

@tmhedberg
Last active December 18, 2015 07:29
Show Gist options
  • Save tmhedberg/5746583 to your computer and use it in GitHub Desktop.
Save tmhedberg/5746583 to your computer and use it in GitHub Desktop.
Mini-EDSL for RPG-style die roll specifiers
-- | Mini-EDSL for RPG-style die roll specifiers
--
-- Examples:
--
-- > Chance> let c = 3 + 2 `d` 20
-- > Chance> roll c
-- > 17
-- > Chance> roll c
-- > 21
-- > Chance> roll c
-- > 36
-- > Chance> let monopolyDice = 2 `d` 6
-- > Chance> roll monopolyDice
-- > 4
-- > Chance> roll monopolyDice
-- > 11
-- > Chance> roll $ 5 + 3 `d` 2
-- > 9
module Chance (Chance, roll, d) where
import Control.Applicative
import Control.Monad
import System.Random
newtype Chance = Chance {roll :: IO Integer}
instance Num Chance where Chance a + Chance b = Chance $ liftA2 (+) a b
Chance a * Chance b = Chance $ liftA2 (*) a b
Chance a - Chance b = Chance $ liftA2 (-) a b
negate (Chance c) = Chance $ fmap negate c
abs (Chance c) = Chance $ fmap abs c
signum (Chance c) = Chance $ fmap signum c
fromInteger = Chance . return
d :: Int -> Integer -> Chance
numDice `d` sides = Chance $ fmap sum $ replicateM numDice rand
where rand = randomRIO (1, sides)
infixl 8 `d`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment