【问题标题】:How to use IO Double as regular Double in Haskell如何在 Haskell 中使用 IO Double 作为常规 Double
【发布时间】:2018-12-16 05:16:12
【问题描述】:

我必须遵循代码

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

【问题讨论】:

  • 我无法重现您使用您提供的代码时遇到的错误,所以我无法为您提供帮助。您必须包含实际导致此错误的代码。请阅读MCVE
  • 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))
  • 不要在 cmets 中发布更新,edit你的问题。
  • IO Double 不是数字,它是产生数字的秘诀(或“动作”)。
  • @luqui 它是-2,因为在编辑之前,它没有提供足够的信息,因此根本无法回答。

标签: haskell random io monads do-notation


【解决方案1】:

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

我们看到Doublerandom 相比,<i>randomIO :: IO <b>Double</b></i> 看起来更有希望。如果我们能以某种方式获得Double“内部”的IO Double类型的“值”。我们能做到吗?

是的,我们可以。这就是“绑定”的用途。在do 表示法中,它是用&lt;- 完成的:

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

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

这就是 Haskell。内部纯粹,外部 I/O(如果不通过 I/O,根据定义,它怎么能与我们通信)。

【讨论】:

    猜你喜欢
    • 2012-04-18
    • 1970-01-01
    • 1970-01-01
    • 2015-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多