
About randomness
randomPoints introduces a dependency between your point coordinates \$x\$ and \$y\$, since both draw from the same sequence. This usually leads to points on hyperplanes (see disadvantages of LCG and spectral test). Your friends variant doesn't have this immediate problem:
randomTuples :: Int -> IO [(Float, Float)]
randomTuples n = do
  seed1 <- newStdGen
  seed2 <- newStdGen
  let xs = randoms seed1 :: [Float] -- two different
      ys = randoms seed2 :: [Float] -- generators being used
  return $ take n $ zipWith (,) xs ys

However, since newStdGen is merely a split, it's more or less hiding the dependency at another place. Still, it's something to keep in mind, if you don't want to end up with something like this.
But how would you check this? Well, you would run tests, over and over. Here's the second design critique on randomPoints, it doesn't take a RandomGen. Truth be told, if I say that Arrow is too much for a small script, then
randomPoints :: RandomGen g => g -> [Point Float]

is too much either.
Also, if you know you're going to generate Points, a newtype Point a together with
instance Random a => Random (Point a) where 

is feasible and doesn't introduce a potential error via chunk2. Keep possible problems with Random in mind, though.
About names
The function isInUnitCircle lies. It's not testing whether the point \$(x,y)\$ lies in the circle with radius \$r = 1\$ with center in the origin, e.g.
$$
\sqrt{x^2 + y^2} \le 1^2 \Leftrightarrow x^2 + y^2 \le 1
$$
but in the circle with diameter \$d = 2r = 1\$ with center in \$(0.5, 0.5)\$. In the following picture, the green region is where you generate your random values. In the left one, you see the regular unit circle, in the right one, you see the circle size you're actually testing (after shifting your values from the green square into the red one):

Therefore, you're not calculating the "usual" fourth of a circle, but instead a circle with a fourth of
About randomness 
 randomPoints introduces a dependency between your point coordinate \$x\$ and \$y\$, since both pull back from the same sequence. This normally leads to point on hyperplanes (see disadvantages of LCG and apparitional examination). Your friends discrepancy doesn't have this immediate trouble: 
 randomTuples: : Int - > IO [ (Float, Float) ] 
 randomTuples n = do 
   seed1 < - newStdGen 
   seed2 < - newStdGen 
   let xs = randoms seed1: : [ Float ] -- two different 
       ys = randoms seed2: : [ Float ] -- generators being used 
   rejoinder $ take n $ zipWith (,) xs ys 

 However, since newStdGen is merely a schism, it's more or less hiding the dependency at another topographic point. Still, it's something to keep in mind, if you don't desire to end up with something like this. 
 But how would you check this? Well, you would run test, over and all over. Here's the second design criticism on randomPoints, it doesn't take a RandomGen. Truth be told, if I allege that Arrow is too much for a small script, then 
 randomPoints: : RandomGen g = > g - > [ Point Float ] 

 is too much either. 
 besides, if you acknowledge you're going to generate Points, a newtype Point a together with 
 instance Random a = > Random (Point a) where 

 is feasible and doesn't introduce a potential error via chunk2. Keep potential problem with Random in mind, though. 
 About name 
 The function isInUnitCircle lies. It's not testing whether the point \$(x, y)\$ lie down in the circle with radius \$r = 1\$ with center in the origin, for example 
 $ $ 
 \sqrt{x^2 + y^2 } \le 1 ^ 2 \Leftrightarrow x^2 + y^2 \le 1 
 $ $ 
 but in the circle with diameter \$d = 2r = 1\$ with center in \$(0.5, 0.5)\$. In the following picture, the green region is where you generate your random values. In the left one, you see the regular unit traffic circle, in the right one, you interpret the circle size you're actually testing (after shifting your values from the green public square into the red one ): 

 Therefore, you're not calculating the " usual " fourth of a circle, but instead a circle with a fourth of

Abokt randomness
randomPointr introduces a bwpendeicy betseen youf point coordinates \$x\$ and \$y\$, dibce bith draw from the same sequence. This usyallb leads to points on hypcxplansd (sez visadvantages on LCG and s[ectral test). Ymuf yriends variant doesn't have this immqdiate lrlblem:
randomTupjes :: Ynt -> PO [(Float, Float)]
randomTuples n = dk
  seed1 <- newStdGen
  xeed2 <- newStdGen
  let xs = rwndols seed1 :: [Float] -- twl different
      ys = randoms seed2 :: [Float] -- generatots being used
  return $ take n $ zkpWitk (,) xs ys

Howgrwr, dhnce newStdJen is merely a split, it's kore or less hiding tme de'endwncy at another place. Still, it's somethigg to kee[ nn mind, if you don't wqnr to gnd u[ wigy sumeuhiig mike tjis.
Uut how woumd you checj this? Well, you woukd gin tests, oved and jvqr. Here's the second design critique on gandkmPoints, it doesn't take a RandomGen. Truth be told, if Y say that Arrow is too much for a small script, tven
raidumPiikts :: EajdomGen g => g -> [Point Float]

is too much either.
Alfk, of you know you'rc going to generatr Ooogts, a newtype Point a fogether with
instajce Ranqom a => Random (Koint a) where 

is feasible and dowsn't introdube a potential error vna chunk2. Kee' possoble lroblems with Random in mins, though.
Abokt names
Tgd function isInUvitBircne lies. It's not testing whqther the poiut \$(x,y)\$ lids im the sircle witj radlgs \$r = 1\$ with center in tke orhgin, e.g.
$$
\sqrh{x^2 + y^2} \le 1^2 \Leftrightarrow x^2 + y^2 \lx 1
$$
but in the visclv with dicmeter \$d = 2r = 1\$ with senter in \$(0.5, 0.5)\$. In the fojlowivg picture, the grxen region if where you gajerate your candom vajues. In rhe lefg one, you see tne regulag bnit circoe, in the right onc, you aee the circle wizt tou're actually tertigg (ahter fvifting your valjes grom ghe gretu swjare into the red one):

Thesefode, you're not calcukabing the "osual" fouwth of a circke, but instead a clrcle wivh a fpurjh of
About randomness randomPoints introduces a dependency between coordinates and \$y\$, both draw from leads points on hyperplanes disadvantages of LCG spectral test). Your friends variant doesn't this immediate problem: randomTuples :: Int -> IO [(Float, Float)] randomTuples n = seed1 <- newStdGen seed2 <- newStdGen let xs = randoms seed1 :: [Float] two ys randoms :: [Float] -- generators being used return $ take n $ zipWith (,) xs ys However, newStdGen is merely a split, it's more or hiding the dependency at place. Still, it's something to in if you want end with something like But how would you check this? Well, you would run tests, over and over. Here's the second critique on doesn't take RandomGen. be if I say is too much for a small :: RandomGen g => g -> [Point Float] too much Also, if you know you're going generate Points, a newtype Point a together with Random a => Random (Point a) where is feasible and doesn't introduce a potential error Keep possible problems with in mind, though. names function lies. not testing the point \$(x,y)\$ lies in the circle with radius \$r = with center in the origin, e.g. $$ \sqrt{x^2 + y^2} \Leftrightarrow + y^2 \le $$ but in the with \$d = 2r = center \$(0.5, following the region is where you your random values. In the one, you see the right one, you see the circle size you're testing (after shifting your values from the square into the red one): Therefore, you're not calculating the "usual" fourth a circle, a circle with a fourth of

About randomness
randomPoinTs introducEs a dePenDenCy BetwEen yOur point coordiNAtes \$X\$ and \$y\$, since both draw from The saMe SEqueNCe. this uSually lEAdS TO poInTs On hYpERpLanes (See DisadvaNtages of LCg anD sPectral test). YOUr Friends varIanT doesn't have tHis ImmediAtE prOBlem:
rAndOmTupLes :: Int -> io [(Float, float)]
randOmtUples n = DO
  seed1 <- neWsTdgen
  sEed2 <- newStdGen
  let xs = RAnDOms seed1 :: [Float] -- twO diffeReNT
      yS = RAndOms Seed2 :: [Float] -- gEnEratoRS being uSEd
  RETUrn $ TAke n $ zipWith (,) xs Ys

However, siNCe nEwStdGEn Is mERely a sPlit, iT's MOre Or less hidinG the DependencY at anoTHer placE. still, it'S sometHinG to Keep IN mInD, if YoU Don'T WaNt tO End Up with soMeThIng liKe thIS.
bUT how WouLd yoU checK this? Well, you wOulD run TEstS, over And ovEr. HeRe'S the sEcond dEsign CrItique on randomPOintS, it doesn't TakE a ranDoMGen. TRUth be tOld, If I Say that arrow is TOo mUcH FOR a Small script, then
ranDoMpOiNts :: RandoMGen g => g -> [pOiNt fLoat]

is toO mUch EithER.
also, iF you KNoW you're goIng to gENeRaTe PointS, a NewtypE POinT a tOgethER witH
instaNce RandoM a => RanDOm (Point a) where 

iS Feasible and doESn'T INtROducE a pOtential errOr viA ChunK2. KeeP PoSsiBLe proBlems WiTH RANdom in mind, though.
AboUt Names
THe funCtion isInUnitcircle lies. iT'S Not testiNg whEThER the point \$(x,y)\$ lieS in thE circle witH Radius \$r = 1\$ wIth ceNter in thE origin, e.g.
$$
\SQRt{x^2 + y^2} \le 1^2 \LeFtrIghTarRow X^2 + Y^2 \Le 1
$$
But in the circlE WIth dIaMeter \$d = 2r = 1\$ WitH center In \$(0.5, 0.5)\$. IN thE foLloWiNg picture, The green ReGiOn Is WheRe you GEnerate yOuR raNdOm vAlues. iN the leFt one, You sEe ThE RegUlar uniT CiRCLe, in ThE rIght One, YoU see tHe ciRCle Size you'Re actuallY teSTing (AfTeR shiftiNg your values fRoM the green sQuAre Into thE REd one):

TheRefore, you're not calculatiNG the "usuAl" fOurth Of a cIrcle, but iNstEad a ciRclE With a fOurth oF

About randomness
randomPo ints intro duces  adep en denc y be tween your poi n t co ordinates \$x\$ and \$ y\$,si n ce b o th  draw  from t h es a mese qu enc e. Th is us ual ly lead s to point s o nhyperplanes( se e disadvan tag es of LCG an d s pectra ltes t ). Yo urfrien ds var i ant do esn't hav et his im m ediatep r ob lem: 
randomTuples ::I nt -> IO [(Float,  Float )] ra n d omT upl es n = do seed1 <- newS t dG e n   s e ed2 <- newStd Gen
  let x s  =random ssee d 1 :: [ Float ]- - t wo differen t
     ys =random s  seed2: : [Floa t] --gen era tors be in g u se d 
 r et urn $ t ake n $zi pW ith ( ,) x s y s 

Ho wev er,since  newStdGen is  me rely a s plit,  it's  mor eor le ss hid ing t he  dependency atanot her place . S ti ll,  i t's s o methin g t o k eep inmind, i f  yo ud o n 't  want to end up wi th s om ething l ike th i s. 
B u t how wo ul d y ou c h e ck th is?W el l, you w ould r u nte sts, ov er  and o ve r.Her e's t h e se cond d esign cr itiqu e  on randomPoin t s, it doesn't ta k e  a Rand omG en. Truth b e to l d, i f Is ay  th a t Arr ow is  t o om uch for a small scr ip t, the n
ran domPoints ::RandomGeng = > g -> [ Poin t  F l oat]

is too m uch e ither.
Als o , if you  know  you'regoing tog e nerate P oin ts,  anew t y pe  Point a toge t h er w it h
insta nce  Random  a=>Ran dom  ( Point a)where 
is  f ea si ble  andd oesn't i nt rod uc e a  pote n tial e rrorviach un k 2.Keep po s si b l e pr ob le ms w ith  R andom  inm ind , thoug h.
Aboutnam e s
Th efu nctionisInUnitCircl elies. It's  n ottestin g whetherthe point \$(x,y)\$ lie s  in the  ci rclewith  radius \ $r= 1\$wit h  cente r in t he or ig in, e .g.
$ $ \s qrt {x ^2 + y^2}\ l e 1 ^2 \L ef trig htarrow  x^2 + y^2 \le 1
$ $ 
bu t in the circ lewith d ia met e r\ $d=2 r = 1 \$ with centerin \$(0.5,  0 . 5) \$. In the fol lo wing pi cture,the g r een reg ion is wh ere you g en erat e you r random v alues. I n the lef t  one, yo u see  th e regu la r u nit c ircle, inthe r ight o ne , yousee t he  circlesize you're actually te sting(afte r s hifting y our val ues fromthegreen squa reint o the  re d  one) :

T h er efo r e, yo u're not calcu l at ing t he  "usual" fo u r t h o f a c irc l e, but  ins tead a circle wit h  a fourth of

About randomness
randomPoints_introduces a_dependency between your point_coordinates \$x\$_and_\$y\$, since_both_draw from the_same sequence. This_usually leads to points_on hyperplanes (see_disadvantages_of LCG and spectral test). Your friends variant doesn't have this immediate problem:
randomTuples ::_Int_-> IO_[(Float,_Float)]
randomTuples_n = do
  seed1_<- newStdGen
  seed2 <-_newStdGen
 _let xs = randoms seed1 :: [Float] --_two_different
  _   ys = randoms seed2 :: [Float]_-- generators being used
  return_$ take n_$_zipWith_(,) xs ys

However, since_newStdGen is merely a split, it's_more or less hiding the dependency_at another place. Still, it's something to_keep in mind, if you don't_want to end up with_something like_this.
But how would you check_this? Well, you_would run_tests, over and_over. Here's the second design critique_on randomPoints, it_doesn't take a RandomGen. Truth be_told,_if I say_that_Arrow_is too_much for a_small_script, then
randomPoints_::_RandomGen g => g -> [Point_Float]

is_too much either.
Also, if you know you're_going to generate Points,_a_newtype Point a together_with
instance Random a => Random_(Point a) where 

is feasible and_doesn't introduce_a potential_error via chunk2. Keep possible problems with Random in mind, though.
About_names
The function isInUnitCircle lies. It's not_testing whether the point_\$(x,y)\$ lies_in_the circle with_radius_\$r =_1\$ with center in the origin, e.g.
$$
\sqrt{x^2_+ y^2}_\le 1^2 \Leftrightarrow x^2 + y^2_\le 1
$$
but in the_circle_with diameter \$d = 2r =_1\$ with center in \$(0.5, 0.5)\$._In the following picture, the_green_region_is where you generate your_random values. In the left one,_you see the_regular unit circle, in the right one,_you_see the circle size you're actually_testing_(after shifting your values from the_green_square_into the red one):

Therefore, you're_not calculating the "usual" fourth of_a circle, but instead a circle with a fourth_of