Skip to content

Instantly share code, notes, and snippets.

@nvanderw
Created August 30, 2012 18:54
Show Gist options
  • Save nvanderw/3537525 to your computer and use it in GitHub Desktop.
Save nvanderw/3537525 to your computer and use it in GitHub Desktop.
Memorable random words from a dictionary
module Main (main) where
import Control.Monad
import Data.Char
import System.IO
import System.Environment
import System.Random
import System.Exit
infixr 3 &?
-- |Composites two predicates together using AND
andPred :: (a -> Bool) -> (a -> Bool) -> a -> Bool
andPred p q n = (p n) && (q n)
-- |Infix version of andPred
(&?) = andPred
-- |Predicate which words must satisfy to be chosen
wordPred :: String -> Bool
wordPred = ((< 10) . length) &? -- Short words
(not . elem '\'') &? -- Don't have apostrophes
(all isAsciiLower) &? -- Contain only lower-case ASCII
((/= 's') . last) -- Are not plural
main :: IO ()
main = do
-- Validate args
args <- getArgs
when ((length args) < 2) $ do
prog <- getProgName
hPutStrLn stderr $ "Usage: " ++ prog ++ " <path-to-dict> <numwords>"
exitWith =<< exitFailure
-- First argument, specifying number of words to choose
let (path:words:_) = args
let numWords = read words :: Int
gen <- getStdGen
dict <- openFile path ReadMode
-- Words in the dictionary
words <- (liftM lines) . hGetContents $ dict
-- Infinite list of random selections from dictionary
let rs = filter wordPred . map (words !!) $
randomRs (0, (length words) - 1) gen
mapM_ putStrLn . take numWords $ rs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment