Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Variables 简单Haskell IORef-“;不能';t匹配类型'IO Int';带有'Int'"E;”can';我看不出是怎么回事';那不一样_Variables_Haskell_Random_Ioref - Fatal编程技术网

Variables 简单Haskell IORef-“;不能';t匹配类型'IO Int';带有'Int'"E;”can';我看不出是怎么回事';那不一样

Variables 简单Haskell IORef-“;不能';t匹配类型'IO Int';带有'Int'"E;”can';我看不出是怎么回事';那不一样,variables,haskell,random,ioref,Variables,Haskell,Random,Ioref,我正在尝试在Haskell中使用IORef创建一个简单的随机数生成器来存储可变变量。我的想法是,我可以初始化种子,然后根据种子生成数字,并为下一个随机整数存储新种子 我得到的全部错误是: random2.hs:9:17: Couldn't match type `IO Int' with `Int' Expected type: IO (IORef Integer) -> (IORef Integer -> IO Int) -&g

我正在尝试在Haskell中使用IORef创建一个简单的随机数生成器来存储可变变量。我的想法是,我可以初始化种子,然后根据种子生成数字,并为下一个随机整数存储新种子

我得到的全部错误是:

random2.hs:9:17:
    Couldn't match type `IO Int' with `Int'
    Expected type: IO (IORef Integer)
                   -> (IORef Integer -> IO Int) -> Int
      Actual type: IO (IORef Integer)
                   -> (IORef Integer -> IO Int) -> IO Int
    In a stmt of a 'do' block: seed <- newIORef 7
    In the expression:
      do { seed <- newIORef 7;
           randomGen (readIORef seed) }
    In an equation for `getRandom':
        getRandom
          = do { seed <- newIORef 7;
                 randomGen (readIORef seed) }

random2.hs:10:17:
    Couldn't match type `(,) Int' with `IO'
    Expected type: IO Int
      Actual type: (Int, Int)
    In the return type of a call of `randomGen'
    In a stmt of a 'do' block: randomGen (readIORef seed)
    In the expression:
      do { seed <- newIORef 7;
           randomGen (readIORef seed) }

random2.hs:10:28:
    Couldn't match expected type `Int' with actual type `IO Integer'
    In the return type of a call of `readIORef'
    In the first argument of `randomGen', namely `(readIORef seed)'
    In a stmt of a 'do' block: randomGen (readIORef seed)
Failed, modules loaded: none.
random2.hs:9:17:
无法将类型'IO Int'与'Int'匹配
预期类型:IO(IORef整数)
->(IORef Integer->IO Int)->Int
实际类型:IO(IORef整数)
->(IORef Integer->IO Int)->IO Int
在“do”块的stmt中:种子(Int,Int)
randomGen x=(x,x+1)
getRandom::Int
getRandom=do
种子尝试:

modulemain其中
导入数据.IORef
进口管制
导入数据.Tuple(fst,snd)
randomGen::Int->(Int,Int)
randomGen x=(x,x+1)
getRandom::IO Int->IO(Int,Int)
getRandom x=do
y试试看:

modulemain其中
导入数据.IORef
进口管制
导入数据.Tuple(fst,snd)
randomGen::Int->(Int,Int)
randomGen x=(x,x+1)
getRandom::IO Int->IO(Int,Int)
getRandom x=do

yHaskell中的
IO Int
Int
类型完全不同。这适用于该表单的任何其他类型,如
可能是Int
字符串Int
。这是Haskell类型系统设计的一部分,使其功能强大。你可以把这个表单中的任何东西想象成一种容器,它被参数化了。因此,您可以执行以下操作

getRandom :: IO Int
getRandom = do
    seed <- newIORef 7           -- IO (IORef Int)
    g <- readIORef seed          -- IO Int
    let (x, newG) = randomGen g  -- (Int, Int)
    writeIORef seed newG         -- IO ()
    return x                     -- IO Int
getRandom::IO Int
getRandom=do

seedHaskell中的
ioint
Int
类型完全不同。这适用于该表单的任何其他类型,如
可能是Int
字符串Int
。这是Haskell类型系统设计的一部分,使其功能强大。你可以把这个表单中的任何东西想象成一种容器,它被参数化了。因此,您可以执行以下操作

getRandom :: IO Int
getRandom = do
    seed <- newIORef 7           -- IO (IORef Int)
    g <- readIORef seed          -- IO Int
    let (x, newG) = randomGen g  -- (Int, Int)
    writeIORef seed newG         -- IO ()
    return x                     -- IO Int
getRandom::IO Int
getRandom=do


seed
randomGen
是纯的,但是
readIORef
返回
IO a
。您需要在do子句中的
randomGen
前面使用
liftM
。另外
getRandom::IO Int
。一旦它是IO,你就无法摆脱它。@dumb0所以我添加了导入控件。Monad,将
getRandom::Int
的定义更改为
getRandom::IO Int
,并将最后一行从
randomGen(readIORef-seed)
更改为
liftM(randomGen(readIORef-seed))
-这就是你刚才描述的吗?因为这会引发另一个错误。我的注释有一个错误:
getRandom::IO(Int,Int)
@dumb0仍然是一个错误-
无法匹配预期的类型
IO(Int,Int)“实际类型为
m0a10->m0r0”
新错误的行数是多少?
randomGen
是纯的,但
readIORef
返回
IO a
。您需要在do子句中的
randomGen
前面使用
liftM
。另外
getRandom::IO Int
。一旦它是IO,你就无法摆脱它。@dumb0所以我添加了导入控件。Monad,将
getRandom::Int
的定义更改为
getRandom::IO Int
,并将最后一行从
randomGen(readIORef-seed)
更改为
liftM(randomGen(readIORef-seed))
-这就是你刚才描述的吗?因为这会引发另一个错误。我的评论有一个错误:
getRandom::IO(Int,Int)
@dumb0仍然是一个错误-
无法将预期的类型
IO(Int,Int)”与实际的类型
m0a10->m0r0'
在什么行号上是新的错误?太棒了,这适用于上述情况。但是因为它现在使用liftM,我不能保存元组中的第二个值,对吗?我想将其保存回IORef,以便下次调用getRandom时返回一个不同的随机数,但这在当前结构中是不可能的?这跟我有什么关系updateIORef@SamHeather您无法避免返回种子并将其传递给下一个调用。
getRandom
中的
IORef
是函数的局部函数,因此您必须以任何方式返回种子,因此使用
IORef
会使生成器变得不纯,而不会为您带来任何好处。如果要使种子传递隐式化,更好的方法是使用
状态
monad.@dumb0我不是想重新发明轮子,只是学习。我试图在Haskell中给出一些非常简单的有状态程序的例子(这个),但是即使这个实现看起来也不是有状态的,因为它每次运行时都返回7,从来没有像我希望的那样改变(递增)——我想这是我的误解。你能想出什么办法让它这样做,或者想出一个不同的简单有状态的问题,我可以看看?好吧,我的错。根据我对哈斯克尔有限的经验,没有国家。一旦getRandom返回,就完成了。如果使用相同的值调用
getRandom
(例如
return4
),则会得到相同的输出。我所做的是创建一个输出,为下次调用
getRandom
时提供随机数和种子(例如,(1,4),其中1是随机数,4是再次调用
getRandom
时使用的数字)。这在某种意义上模拟了状态。希望这有帮助…太棒了,这对上面的工作。但是因为它现在使用liftM,我不能保存元组中的第二个值,对吗?我想将其保存回IORef,以便下次调用getRandom时返回一个不同的随机数,但这在当前结构中是不可能的?这跟我有什么关系updateIORef@SamHeather您无法避免返回种子并将其传递给下一个调用。
getRandom
中的
IORef
是函数的局部函数,因此您必须以任何方式返回种子,因此使用
IORef
使您的生成器
module Main where
import Data.IORef
import Control.Monad
import Data.Tuple(fst,snd)

randomGen :: Int -> (Int, Int)
randomGen x = (x,x+1)

getRandom :: IO Int -> IO (Int,Int)
getRandom x = do
    y <- x
    seed <- newIORef y
    liftM randomGen $ readIORef seed
getRandom :: IO Int
getRandom = do
    seed <- newIORef 7           -- IO (IORef Int)
    g <- readIORef seed          -- IO Int
    let (x, newG) = randomGen g  -- (Int, Int)
    writeIORef seed newG         -- IO ()
    return x                     -- IO Int