{- | Generates a password,
     containing upper case letters,
     lower case letters,
     digits and symbols.
     Entropy of about 115 bits for length 18. -}
safe :: Schema
safe = withDefaultSize 18 $ \ s -> do
    let number = max s 4
        lBound = max 1 $ floor $ number % 8
        uBound = ceiling $ number % 4
    nUpper <- inRange (lBound, uBound)
    nDigit <- inRange (lBound, uBound)
    nSpecial <- inRange (lBound, uBound)
    let nLower = number - nUpper - nSpecial - nDigit
    uppers <- replicateM nUpper upper
    digits <- replicateM nDigit digit
    specials <- replicateM nSpecial special
    lowers <- replicateM nLower lower
    shuffle (uppers <> digits <> specials <> lowers)

{- | Generates a password,
     containing upper case letters,
     lower case letters and
     digits, but no symbols.
     Entropy of about 104.2 bits for length 18. -}
safe :: Schema
safe = withDefaultSize 18 $ \ s -> do
    let number = max s 4
        lBound = max 1 $ floor $ number % 8
        uBound = ceiling $ number % 4
    nUpper <- inRange (lBound, uBound)
    nDigit <- inRange (lBound, uBound)
    nSpecial <- inRange (lBound, uBound)
    let nLower = number - nUpper - nSpecial - nDigit
    uppers <- replicateM nUpper upper
    digits <- replicateM nDigit digit
    specials <- replicateM nSpecial special
    lowers <- replicateM nLower lower
    shuffle (uppers <> digits <> specials <> lowers)

{- | Generates a password,
     containing upper case letters,
     lower case letters and
     digits, but no symbols.
     Entropy of about 104.2 bits for length 18. -}
safe = withDefaultSize 18 $ \ s -> do
    let number = max s 4
        lBound = max 1 $ floor $ number % 8
        uBound = ceiling $ number % 4
    nUpper <- inRange (lBound, uBound)
    nDigit <- inRange (lBound, uBound)
    nSpecial <- inRange (lBound, uBound)
    let nLower = number - nUpper - nSpecial - nDigit
    uppers <- replicateM nUpper upper
    digits <- replicateM nDigit digit
    specials <- replicateM nSpecial special
    lowers <- replicateM nLower lower
    shuffle (uppers <> digits <> specials <> lowers)

{- | Generates a password,
     containing upper case letters,
     lower case letters and
     digits, but no symbols.
     Entropy of about 104.2 bits for length 18. -}