random :: MonadBooks m => Maybe Text -> m ()
random lname = do
    books  <- maybe toBeRead matchSection lname
    author <- select $ Set.map bookAuthor books
    book   <- select $ Set.filter ((== author) . bookAuthor) books
    putLn $ formatBook book
  where
    select s = liftIO $ do
        i <- randomRIO (0, Set.size s - 1)
        return $ Set.toAscList s !! i
random :: MonadBooks m => Maybe Text -> m ()
random lname = do
    books  <- maybe toBeRead matchSection lname
    author <- select $ Set.map bookAuthor books
    book   <- select $ Set.filter ((== author) . bookAuthor) books
    putLn $ formatBook book
  where
    select s = liftIO $ do
        i <- randomRIO (0, Set.size s - 1)
        return $ Set.toAscList s !! i
random lname = do
    books  <- maybe toBeRead matchSection lname
    author <- select $ Set.map bookAuthor books
    book   <- select $ Set.filter ((== author) . bookAuthor) books
    putLn $ formatBook book
  where
    select s = liftIO $ do
        i <- randomRIO (0, Set.size s - 1)
        return $ Set.toAscList s !! i