将IO输出带到另一个纯Haskell函数

将IO输出带到另一个纯Haskell函数,haskell,io,Haskell,Io,我是哈斯克尔的新手,英语也不是我的第一语言,所以请不要因为一些打字错误或问题表述不当而对这篇文章进行评分:对我来说,这是一场真正的斗争 无论如何:我正在尝试生成随机坐标(Int,Int),然后在另一个Haskell函数中使用它。但是我在将IO函数结果“导出”到第二类纯Haskell函数时遇到了一些问题 下面是一个我认为并希望能恰当说明我的问题的例子: genRandomPair = genRandNr genRandNr :: IO (Int,Int) genRandNr = do f

我是哈斯克尔的新手,英语也不是我的第一语言,所以请不要因为一些打字错误或问题表述不当而对这篇文章进行评分:对我来说,这是一场真正的斗争

无论如何:我正在尝试生成随机坐标
(Int,Int)
,然后在另一个Haskell函数中使用它。但是我在将IO函数结果“导出”到第二类纯Haskell函数时遇到了一些问题

下面是一个我认为并希望能恰当说明我的问题的例子:

genRandomPair = genRandNr

genRandNr :: IO (Int,Int)
genRandNr = do
    firstRandom <- randomRIO (1,10)
    secondRandom <- randomRIO (1,10)
    return (firstRandom,secondRandom)
genRandomPair=genRandNr
genRandNr::IO(Int,Int)
genRandNr=do
firstRandom如果您有am
IO(Int,Int)
值和一个函数,例如,
(Int,Int)
,您可以使用
fmap
通过纯函数映射不纯结果:

fmap myPureFunction anImpureTuple
不过,通常情况下,您可能希望更改代码的类型

我知道你对Haskell是新手,但不幸的是,Haskell中的随机性可能不是一个好的入门话题。Haskell明确区分了纯函数和不纯行为,随机性本质上是不纯的


要实现依赖随机性的函数的优雅分解,需要理解Haskell的一些中间抽象,例如函子(在
fmap
的情况下)或类型类(理解
RandomGen
)。

Haskell中纯函数的概念是,如果某个纯函数采用相同的参数,它总是返回相同的结果。在您的情况下,这意味着您的
genrandom对
只是一对
Int
s,这对不依赖于时间、日期、您的系统等等。因此,您不能只创建没有
IO
的随机对


但是,您确实可以使用函数
unsafePerformIO
或类似的其他函数来实现这一点。通常不建议这样做,但是,如果您想…

genRandNr
IO(Int,Int)
,但您可以将其键入为
IO()
。还有,
genRandCoord
应该是什么?抱歉@Aplet123,我编辑了它。上面的函数主要是为了说明我希望genRandomPair具有与genRandNr相同的结果。嗯,不完全一样。但是我想在genRandomPair内部处理结果。您可以再次使用
do
表示法:
genRandomPair=do\pair@NoNameAgent我想您需要向我们提供更多关于您想在
genRandomPair
中执行什么操作的信息。按原样(编辑后),代码应该可以工作
genRandomPair
使用
genRandNr
,并具有类型
IO(Int,Int)
。您是否希望能够给
genRandomPair
类型
(Int,Int)
?这是不可能做到的;如果这是你的问题,答案可以详细说明为什么它不能这样工作,为什么你不需要这样做。但目前还不完全清楚你是否在问这个问题。我知道你已经用“不推荐”来限定它,但它不仅应该几乎总是避免
unsafePerformIO
,而且如果你生成随机数,它确实应该避免。通过使用
unsafePerformIO
你是在说“这真的是一个纯函数,即使没有IO-compiler我无法表达它,但你必须相信我”。但当然,随机性从根本上来说并不是纯粹的。人们在哪里使用了
unsafePerformIO
来实现这一目的,有几个问题,他们想知道为什么他们的函数总是给出相同的数字。。。