RandomDotOrg-0.2: System/Random/Atmosphere.hs
module System.Random.Atmosphere (
getRandomNumbers -- :: Int -> Int -> Int -> IO (Either String [Int])
, getRandomSequence -- :: Int -> Int -> IO (Either String [Int])
, getRandomStrings -- :: Int -> Int -> Bool -> Bool -> Bool -> Bool -> IO (Either String [String])
, getQuota -- :: IO (Either String Int)
) where
import Data.Either
import Network.URI
import Network.HTTP.Simple
-- URI for integer generation
int_uri num min max
= concat [ "http://random.org/integers/?num=", show num
, "&min=", show min
, "&max=", show max
, "&col=1&base=10&format=plain&rnd=new" ]
-- URI for sequence generation
seq_uri min max
= concat [ "http://www.random.org/sequences/?min=", show min
, "&max=", show max
, "&format=plain&rnd=new" ]
-- URI for string generation
str_uri num len digits uppercase lowercase unique
= concat [ "http://www.random.org/strings/?num=", show num
, "&len=", show len
, "&digits=", if digits == True then "on" else "off"
, "&upperalpha=", if uppercase == True then "on" else "off"
, "&loweralpha=", if lowercase == True then "on" else "off"
, "&unique=", if unique == True then "on" else "off"
, "&format=plain&rnd=new" ]
-- | Used to get a list of random numbers from http://random.org.
-- Note: the minimum must be greater than the maximum. The maximum
-- amount of numbers you can retrieve is 10,000, and the numbers
-- themselves are limited to a range of +/- 1,000,000,000 (inclusive)
getRandomNumbers :: Int -- ^ Number of integers to get
-> Int -- ^ Minimum number
-> Int -- ^ Maximum number
-> IO (Either String [Int]) -- ^ Returns either an error string or the list of integers
getRandomNumbers num min max
| max <= min = return $ Left "err: minimum must be greater than maximum"
| num > 10000 = return $ Left "err: can't retrieve more than 10,000 numbers"
| abs min > 1000000000 = return $ Left "err: min can't be more/less than 1,000,000,000"
| abs max > 1000000000 = return $ Left "err: max can't be more/less than 1,000,000,000"
| otherwise = do let uri' = parseURI (int_uri num min max)
case uri' of
Nothing -> return $ Left "err: parseURI returned Nothing"
Just u -> retrieve u (map read . lines)
-- | This is just like 'getRandomNumbers', but instead it will
-- randomize a given interval of integers. The limits on the minimum/maximum
-- are -1e9 to 1e9, inclusive. The interval itself must be less than 10,000.
getRandomSequence :: Int -- ^ Minimum
-> Int -- ^ Maximum
-> IO (Either String [Int])
getRandomSequence min max
| max <= min = return $ Left "err: max must be greater than min"
| abs max > 1000000000 = return $ Left "err: max can't be greater/less than +/-1e9"
| abs min > 1000000000 = return $ Left "err: min can't be greater/less than +/-1e9"
| (max - min)+1 > 10000 = return $ Left "err: sequence must be smaller than 10,000"
| otherwise = do let uri = parseURI (seq_uri min max)
case uri of
Nothing -> return $ Left "err: parseURI returned Nothing"
Just u -> retrieve u (map read . lines)
-- | Generate random strings. NOTE: if you specify to generate unique
-- strings, the amount you want to retrieve /must/ be less than or equal to the
-- amount of strings that exist within the character set you specify.
-- In the future there will be a check for this, but you have to be sure as of
-- right now.
getRandomStrings :: Int -- ^ Number of strings requested, max is 10,000
-> Int -- ^ Length of each string, max is 20
-> Bool -- ^ Should digits be allowed?
-> Bool -- ^ Should uppercase be allowed?
-> Bool -- ^ Should lowercase be allowed?
-> Bool -- ^ Should each string be unique?
-> IO (Either String [String])
getRandomStrings num len digits uppercase lowercase unique
| num > 10000 = return $ Left "err: maximum number of strings is 10,000"
| len > 20 = return $ Left "err: maximum str len is 20"
| otherwise = do let uri = parseURI (str_uri num len digits uppercase lowercase unique)
case uri of
Nothing -> return $ Left "err: parseURI returned Nothing"
Just u' -> retrieve u' lines
-- | Used to check how much of your random.org quota you have. Please see
-- 'http://random.org/quota/' for more info.
getQuota :: IO (Either String Int)
getQuota = do let uri = parseURI "http://random.org/quota/?format=plain"
case uri of
Nothing -> return $ Left "err: parseURI returned Nothing"
Just u -> retrieve u read
-- helper utility that calls httpGet for us
-- it applies some function to the returned string so we can remove some
-- boilerplate
retrieve uri f = do s <- httpGet uri
case s of
Nothing -> return $ Left "err: httpGet returned nothing"
Just s' -> return $ Right (f s')