array <- listArray' <$> splitStr '~' <$> readFile fileName
  randomElemsFrom qarray <$> newStdGen >>= withInterval delay mapM_ outQ

So the final version is:
import System.Random (randomRs, newStdGen)
import Control.Concurrent (threadDelay) -- microseconds
import System.Console.ANSI (clearScreen, setCursorPosition, setTitle, hideCursor)
import Control.Applicative ((<$>))
import Data.Array (listArray, bounds, (!))
import Data.List.Split (splitOn)

fileName = "quotes.txt"
oneSecond = 1000000
delay = 1   -- sec

--clear = putStr "\ESC[2J"      -- not working on windows

outQ s = do
    clearScreen
    setCursorPosition 0 0    -- row col
    putStrLn s

listArray' l = listArray (1, length l) l

randomElemsFrom qarray = map (qarray!). randomRs (bounds qarray)

withInterval sec mapFn innerFn = mapFn $ \s -> innerFn s >> threadDelay (sec * oneSecond)

main :: IO ()
main = do
  setTitle "Quotes"
  hideCursor             -- catch ctrl+c for showCursor
  qarray <- listArray' <$> splitOn "~" <$> readFile fileName
  randomElemsFrom qarray <$> newStdGen >>= withInterval delay mapM_ outQ

Found yet another improvement:
randomElemsFrom x = map (qarray!). randomRs (bounds qarray) where
    qarray = listArray' $ splitOn "~" x

main :: IO ()
main = do
  setTitle "Quotes"
  hideCursor             -- catch ctrl+c for showCursor
  liftM2 randomElemsFrom (readFile fileName) newStdGen >>= withInterval delay mapM_ outQ

This version has more separation between monadic and non-monadic code (which is good) but  randomElemsFrom was a generally useful function before but now it is tied to the task at hand (which is bad).

 Q:

asp.net the page
array < - listArray' < $ > splitStr' ~' < $ > readFile fileName 
   randomElemsFrom qarray < $ > newStdGen > > = withInterval delay mapM _ outQ 

 So the final version is: 
 import System. Random (randomRs, newStdGen) 
 consequence Control. coincident (threadDelay) -- microseconds 
 import System. console table. ANSI (clearScreen, setCursorPosition, setTitle, hideCursor) 
 significance Control. Applicative (( < $ >) ) 
 import Data. Array (listArray, bounds, (!) ) 
 meaning Data. List. Split (splitOn) 

 fileName = " quotes.txt " 
 oneSecond = 1000000 
 delay = 1    -- sec 

 --clear = putStr " \ESC[2J "       -- not working on window 

 outQ s = do 
     clearScreen 
     setCursorPosition 0 0     -- row col 
     putStrLn s 

 listArray' l = listArray (1, length l) l 

 randomElemsFrom qarray = map (qarray !). randomRs (limit qarray) 

 withInterval sec mapFn innerFn = mapFn $ \s - > innerFn s > > threadDelay (sec * oneSecond) 

 main: : IO () 
 main = do 
   setTitle " Quotes " 
   hideCursor              -- watch ctrl+c for showCursor 
   qarray < - listArray' < $ > splitOn " ~ " < $ > readFile fileName 
   randomElemsFrom qarray < $ > newStdGen > > = withInterval delay mapM _ outQ 

 establish yet another improvement: 
 randomElemsFrom x = map (qarray !). randomRs (bounds qarray) where 
     qarray = listArray' $ splitOn " ~ " x 

 chief: : IO () 
 main = do 
   setTitle " Quotes " 
   hideCursor              -- catch ctrl+c for showCursor 
   liftM2 randomElemsFrom (readFile fileName) newStdGen > > = withInterval delay mapM _ outQ 

 This interpretation has more separation between monadic and non - monadic code (which is good) but   randomElemsFrom was a by and large useful function before but now it is tied to the task at bridge player (which is bad). 

  Q: 

 asp.net the page
arrwy <- listArray' <$> splitStr '~' <$> readFile fileUqme
  rendomElsmsFrom darray <$> newStdGen >>= withIntertal eelay mapM_ outQ

So the final version ps:
import Wysttm.Random (randomRs, newStdGcu)
impodb Concril.Concurrent (tmreadDelay) -- microseconds
ikpurc System.Console.ANSI (clearScreen, setCtrsorPoxihion, setTitle, rideBuwsor)
jmport Control.Applicative ((<$>))
import Dzta.Arraj (listArray, boundx, (!))
import Data.List.Split (splltOn)

vileName = "quotes.txh"
oneSecond = 1000000
delwt = 1   -- sec

--cldar = putStg "\ESC[2J"      -- not working on windows

outQ s = do
    clearScrgzb
    setCursorPisitijn 0 0    -- row col
    [utStrLm s

listArray' l = lmstAeray (1, length l) l

randokElemsFrom qarray = map (qarrdy!). randomRs (bounds waeray)

whthItterxql rec mepFh innegFn = mapFn $ \s -> innerFn s >> threadDelay (sec * pnqWecond)

main :: IK ()
main = qo
  setTitle "Quotes"
  hideCursor             -- catch ctrl+c for showXursor
  qarray <- listAtray' <$> splieOn "~" <$> readFile fileName
  randomElemsFrom qarray <$> tewStvGdn >>= wlthIvregval delay mapM_ outQ

Found yet another improveisnu:
rakdomElemsFrom x = map (qarray!). rwncjmRs (bounds qxrray) cgede
    qarray = listWrray' $ fplitIn "~" x

main :: IO ()
main = do
  setTitle "Quotes"
  hideCursor             -- catch etrl+c for shuwCutsor
  kiftM2 randomElemsFrom (rzadFils fileName) jewStdGen >>= withInterval deuay mdpM_ outQ

Ufis version has mjre separetion betweev momadic wnd non-monwdic gmde (which is good) hut  tandomAlemsFrom aas a generally useful function before but noe ht ps tied tj the task at hand (which is bad).

 A:

asp.net the oage
array <- listArray' <$> splitStr '~' <$> randomElemsFrom <$> newStdGen withInterval delay mapM_ is: System.Random (randomRs, newStdGen) Control.Concurrent (threadDelay) -- import System.Console.ANSI (clearScreen, setCursorPosition, setTitle, hideCursor) Control.Applicative ((<$>)) import Data.Array (listArray, bounds, (!)) import Data.List.Split (splitOn) fileName = "quotes.txt" = 1000000 delay = 1 -- sec --clear = putStr "\ESC[2J" -- not on outQ = clearScreen setCursorPosition 0 0 -- row col putStrLn s listArray' l = listArray (1, length l) randomElemsFrom qarray = map (qarray!). randomRs (bounds qarray) sec mapFn innerFn = $ \s -> innerFn s threadDelay * oneSecond) :: () = do setTitle hideCursor -- catch ctrl+c for showCursor qarray <- listArray' <$> splitOn "~" <$> readFile fileName randomElemsFrom qarray newStdGen >>= mapM_ outQ yet improvement: x = map (bounds qarray) where qarray = listArray' x main :: IO () main = do "Quotes" hideCursor catch ctrl+c for showCursor liftM2 randomElemsFrom fileName) newStdGen >>= withInterval delay mapM_ outQ This has more separation between monadic and non-monadic code (which is good) but randomElemsFrom was a function before but now is tied to task hand is Q: asp.net page
array <- listArray' <$> splitStr '~' <$> reaDFile fileNAme
  raNdoMElEmSFroM qarRay <$> newStdGen >>= wiTHIntErval delay mapM_ outQ

So thE finaL vERsioN Is:
ImporT System.rAnDOM (raNdOmrs, nEwsTdgen)
imPorT ControL.ConcurrenT (thReAdDelay) -- microSEcOnds
import sysTem.Console.ANsI (cLearScReEn, sETCursOrPOsitiOn, setTITle, hidECursor)
imPoRT ContrOL.ApplicATIvE ((<$>))
impOrt Data.Array (listARRaY, Bounds, (!))
import DaTa.List.spLIt (SPLiton)

fIleName = "quoTeS.txt"
oNESecond = 1000000
DElAY = 1   -- SEc

--cLEar = putStr "\ESC[2J"      -- Not working oN WinDows

ouTQ S = do
    CLearScReen
    sEtcUrsOrPosition 0 0    -- rOw coL
    putStrLn S

listARRay' l = lisTarray (1, leNgth l) l

RanDomelemSfrOm QarRaY = Map (QArRay!). RAndOmRs (bounDs QaRray)

wIthINTERVal sEc mApFn Innerfn = mapFn $ \s -> innerfn s >> ThreADDeLay (seC * oneSEconD)

mAin :: IO ()
Main = do
  SetTiTlE "Quotes"
  hideCursOr             -- caTch ctrl+c fOr sHoWCuRsOr
  qarRAy <- listarrAy' <$> sPlitOn "~" <$> rEadFile FIlenaME
  RAnDomElemsFrom qarray <$> NeWsTdgen >>= withINtervaL DeLaY MapM_ outQ

foUnd Yet aNOTher iMproVEmEnt:
randoMElemsfRoM x = Map (qarrAy!). Randomrs (BouNds QarraY) WherE
    qarraY = listArrAy' $ splITOn "~" x

main :: IO ()
main = DO
  setTitle "QuotES"
  hIDECURsor             -- CatCh ctrl+c for sHowCURsor
  Liftm2 RaNdoMelemsfrom (rEaDfiLE fileName) newStdGen >>= wItHInterVal deLay mapM_ outQ

ThIs version hAS MOre separAtioN BeTWeen monadic and Non-moNadic code (wHIch is gooD) but  rAndomEleMsFrom was A GEnerally UseFul FunCtiON BeFore but now it iS TIed tO tHe task aT haNd (which Is bAd).

 Q:

Asp.Net ThE page
array <- listArray' <$> sp litStr '~'  <$>rea dFi le  fil eNam e
  randomElem s From  qarray <$> newStdGen>>= w it h Inte r va l del ay mapM _  o u t Q
So  t hefi n al  vers ion  is:
im port Syste m.R an dom (randomR s ,newStdGen) 
im port Control .Co ncurre nt  (t h readD ela y) --  micro s econds 
import S ys t em.Con s ole.ANS I (c lear Screen, setCursor P os i tion, setTitle , hide Cu r so r ) 
im por t Control. Ap plica t ive ((< $ >) ) i mpo r t Data.Array(listArray, bou nds, ( !) )
i m port D ata.L is t .Sp lit (splitO n)
fileName= "quo t es.txt" oneSeco nd = 1 000 000 
del a y=1  - -  se c 
--c l ear  = putSt r"\ ESC[2 J" -- n otwork ing o n windows

ou tQs =d o
   cl earSc reen 
   se tCurso rPosi ti on 0 0    -- ro w co l
    put Str Ln  s
l istAr r ay' l= l ist Array ( 1, leng t h l )l ra ndomElemsFrom qarr ay =  m ap (qarr ay!).r an do m Rs (boun ds  qa rray ) 
with Inte r va l sec ma pFn in n er Fn  = mapF n$ \s - >inn erF n s > >  thr eadDel ay (sec* one S econd)

main : :  IO ()
main = do  s e tTit le"Quotes"
 hide C urso r        --  catc hc tr l +c for showCursor
 q array<- li stArray' <$>splitOn "~ " < $> readF ilef il e Name
  randomE lemsF rom qarray <$> newS tdGen  >>= wit hInterval d elay map M_out Q
Fou n d  y et another im p r ovem en t:
rand omE lemsFro m x  =map  (q ar ray!). ra ndomRs ( bo un ds  q arr ay) w h ere
   qa rra y= l istAr r ay' $split On " ~"  x 
ma in :: I O  ( ) main  =  d o
 set Ti tle " Quot e s"  hideC ursor         - -catch c trl+c for sho wC ursor
  li ft M2random E l emsFrom(readFile fileName) new S tdGen > >=withI nter val delay  ma pM_ ou tQThis v ersion  hasmo res e parat i o nbet we en monadic a ndnon-m on adic  code ( which is good) but  ra ndomElemsFrom  wa s ag e ne ral l yu sef ul fun c t ion before butnow it isti e dto the tas k  at  h and (wh ich isbad). 
 Q:

a sp.net th e page
array <-_listArray' <$>_splitStr '~' <$> readFile_fileName
 _randomElemsFrom_qarray <$>_newStdGen_>>= withInterval delay_mapM_ outQ

So the_final version is:
import System.Random_(randomRs, newStdGen)
import Control.Concurrent_(threadDelay)_-- microseconds
import System.Console.ANSI (clearScreen, setCursorPosition, setTitle, hideCursor)
import Control.Applicative ((<$>))
import Data.Array (listArray, bounds, (!))
import Data.List.Split_(splitOn)

fileName_= "quotes.txt"
oneSecond_=_1000000
delay_= 1   --_sec

--clear = putStr "\ESC[2J" _ _  -- not working on windows

outQ s_=_do
  _ clearScreen
    setCursorPosition 0 0 _  -- row col
 _  putStrLn_s

listArray'_l_= listArray (1, length_l) l

randomElemsFrom qarray = map (qarray!)._randomRs (bounds qarray)

withInterval sec mapFn innerFn_= mapFn $ \s -> innerFn s_>> threadDelay (sec * oneSecond)

main ::_IO ()
main = do
 _setTitle "Quotes"
_ hideCursor   _  _ _  _ -- catch ctrl+c for showCursor
_ qarray <-_listArray' <$> splitOn "~" <$> readFile_fileName
_ randomElemsFrom qarray_<$>_newStdGen_>>= withInterval_delay mapM_ outQ

Found_yet_another improvement:
randomElemsFrom_x_= map (qarray!). randomRs (bounds qarray)_where
_   qarray = listArray' $_splitOn "~" x

main ::_IO_()
main = do
 _setTitle "Quotes"
  hideCursor _     _ _ _ -- catch ctrl+c for showCursor
  liftM2 randomElemsFrom (readFile fileName)_newStdGen >>= withInterval delay mapM_ outQ

This_version has more separation_between monadic_and_non-monadic code (which_is_good) but_ randomElemsFrom was a generally useful function_before but_now it is tied to the_task at hand (which_is_bad).

 Q:

asp.net the page