Last active
December 18, 2015 07:29
-
-
Save tmhedberg/5746583 to your computer and use it in GitHub Desktop.
Mini-EDSL for RPG-style die roll specifiers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- | 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