无法将类型'IO'与'[]'

问题描述 投票:0回答:2

我编写了一个函数以生成两个随机数,然后将其传递给另一个函数以在其中使用它们。该代码是:

randomIntInRange :: (Int, Int, Int, Int) -> Board
randomIntInRange (min,max,min2,max2) = do r <- randomRIO (min, max)
                                          r2 <- randomRIO (min2, max2)
                                          randomCherryPosition (r, r2)

并且此函数在其'do'块中调用的函数是:

randomCherryPosition :: (Int, Int) -> Board
randomCherryPosition (x, y) = initialBoard & element y . element x .~ C

其中initialBoard是列表列表,C是预定义的数据类型。我正在使用lens更改列表中的值。运行它会给我错误:

Couldn't match type ‘IO’ with ‘[]’
      Expected type: [Int]
        Actual type: IO Int

对于r和r2行。我完全不知道这是怎么回事,或者我做错了什么,所以我将不胜感激任何帮助。

haskell random io lens gloss
2个回答
3
投票

[randomRIO具有类型IO Int,而不是Int。只要您使用任何IO功能,您周围的功能也必须位于IO中:

randomIntInRange :: (Int, Int, Int, Int) -> IO Board
randomIntInRange (min,max,min2,max2) = do r <- randomRIO (min, max)
                                          r2 <- randomRIO (min2, max2)
                                          pure $ randomCherryPosition (r, r2)

randomRIO不是纯函数。每次返回一个不同的值。 Haskell禁止此类功能。禁止使用此类功能有很多好处,我将在这里介绍。但是,如果将其包装在IO中,则可以具有这样的功能。类型IO Int的意思是“ 它是一个程序,在执行时将产生一个Int”。因此,当您调用randomRIO (min, max)时,它不会返回Int,而是一个程序,您可以执行该程序以获取Int。您可以通过带有左箭头的do表示法执行程序,但是结果也将是类似的程序。


3
投票
不幸的是,没有完美的解决方案。已经在Stackoverflow上进行了讨论,例如here
© www.soinside.com 2019 - 2024. All rights reserved.