4

我必须遵循代码

isInCircle::Double->Double->Bool
isInCircle p1 p2 = sqrt((p1*p1)+(p2*p2)) <= 1

当我打电话时

isInCircle (random :: Double) (random :: Double)

我收到这个错误

* Couldn't match expected type `Double' with actual type `g0 -> (a0, g0)'

如果我将isInCircle函数的参数更改为IO Double我得到错误sqrt和添加......

你能帮助我吗?我的代码:

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
4

1 回答 1

7

在 GHCi 提示符下检查它,

> :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'

我们看到代替random, for Double,看起来更有希望。如果我们能以某种方式在“内部”获得“价值”的类型。我们能做到吗?randomIO :: IO DoubleDoubleIO Double

我们可以。这就是“绑定”的用途。在do符号中,它是通过以下方式完成的<-

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 ()

函数本身没有改变,isInCircle也不需要改变。它仍然是对两个纯值进行操作的同一个函数。但是我们将它嵌入到组合IO计算配方中,该配方由较小IO的计算配方(包括“内置”randomIO配方)构建,这样当执行结果组合(组合?)计算 - 由命名值引用/描述main- 时,它将使用通过两个s获得的两个值的函数。inInCirclerandomIO

那是哈斯克尔。内部纯粹,外部 I/O(如果不是——根据定义——通过 I/O ,它怎么能与我们通信)。

于 2018-07-08T08:39:43.120 回答