I have to following code
isInCircle::Double->Double->Bool
isInCircle p1 p2 = sqrt((p1*p1)+(p2*p2)) <= 1
and when I make a call like
isInCircle (random :: Double) (random :: Double)
I get this error
* Couldn't match expected type `Double' with actual type `g0 -> (a0, g0)'
If I change the argument of isInCircle
function to IO Double
I get errors with sqrt
and addition...
Can you help me? My code:
import System.Random
main :: IO ()
main = do
if isInCircle (random :: Double) (random :: Double)
then print "True"
else print "False"
isInCircle::Double->Double->Bool
isInCircle p1 p2 = sqrt((p1*p1)+(p2*p2)) <= 1
Checking it out at the GHCi prompt,
> :i Random
class Random a where
randomR :: RandomGen g => (a, a) -> g -> (a, g)
random :: RandomGen g => g -> (a, g)
randomRs :: RandomGen g => (a, a) -> g -> [a]
randoms :: RandomGen g => g -> [a]
randomRIO :: (a, a) -> IO a
randomIO :: IO a
-- Defined in `System.Random'
instance Random Integer -- Defined in `System.Random'
instance Random Int -- Defined in `System.Random'
instance Random Float -- Defined in `System.Random'
instance Random Double -- Defined in `System.Random'
instance Random Char -- Defined in `System.Random'
instance Random Bool -- Defined in `System.Random'
we see that instead of random
, for Double
, randomIO :: IO Double
looks much more promising. If only we could somehow get at the Double
"inside" the IO Double
type of "value". Can we do it?
Yes we can. That's what the "bind" is for. In do
notation it is done with <-
:
import System.Random
main :: IO ()
main = do
-- if isInCircle (random :: Double) (random :: Double)
x <- (randomIO :: IO Double) -- thus, x :: Double
y <- (randomIO :: IO Double) -- thus, y :: Double
if isInCircle x y
then print "True" -- print "True" :: IO ()
else print "False" -- (if ... ...) :: IO ()
The pure function isInCircle
itself isn't changed nor does it need to be. It is still the same pure function operating on two pure values. But we embed it in a combined IO
computation recipe, built from smaller IO
computation recipes (including the "built-in" randomIO
recipe) such that when the resulting combined (composed?) computation – referred to / described by the value named main
– is performed, it will use the pure function inInCircle
with the two values obtained through the two randomIO
s.
That's Haskell. Pure on the inside, I/O on the outside (and how else could it communicate with us if not – by definition – through I/O).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With