swa*_*lay 0 haskell functional-programming
所以在我的项目中,我有一个返回数组的常量函数:
import System.Random
giveList :: [Int]
giveList = [8,9,4,5,2]
Run Code Online (Sandbox Code Playgroud)
我想从该列表中随机选择一个元素,如下所示:
seed::Int
seed = 40
generator = mkStdGen seed
giveRandomElement :: Int
giveRandomElement = giveList !! rand where
n = length tetrominoes
(rand,generator) = randomR (0,(n-1)) generator
Run Code Online (Sandbox Code Playgroud)
但是,由于生成器,这不能编译,我想将生成器保持为全局变量,所以我不必继续将它赋予函数.我也不想处理IO包装器,所以我能用这种方式做什么?
谢谢你的帮助:-)
一个有效的代码示例
import System.Random
seed::Int
seed = 40
giveList :: [Int]
giveList = [8,9,4,5,2]
generator = mkStdGen seed
giveRandomElement :: Int
giveRandomElement = giveList !! rand where
n = length giveList
(rand, _) = randomR (0,(n-1)) generator
Run Code Online (Sandbox Code Playgroud)
但这可能不会,你想要什么.
giveRandomElement将始终产生相同的结果.它是一个没有任何输入的纯函数,那么它应该怎么做?它只能是不变的.
您需要使用IO或者需要通过代码来处理生成器并在某处跟踪它.
你得到的编译器错误:
test.hs:14:23: error:
• Ambiguous type variable ‘g0’ arising from a use of ‘randomR’
prevents the constraint ‘(RandomGen g0)’ from being solved.
Relevant bindings include generator :: g0 (bound at test.hs:14:10)
Probable fix: use a type annotation to specify what ‘g0’ should be.
These potential instance exist:
instance RandomGen StdGen -- Defined in ‘System.Random’
• In the expression: randomR (0, (n - 1)) generator
In a pattern binding:
(rand, generator) = randomR (0, (n - 1)) generator
In an equation for ‘giveRandomElement’:
giveRandomElement
= giveList !! rand
where
n = length giveList
(rand, generator) = randomR (0, (n - 1)) generator
|
14 | (rand, generator) = randomR (0,(n-1)) generator
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)
是因为你定义的符号generator中giveRandomElement的自我,因此编译器的这方面不能推断出它的类型.(generator在这种情况下没有使用顶级声明,因为(rand, generator) =已经在等号后面隐藏了符号.
我想将生成器保留为全局变量,因此我不必继续将其提供给函数。我也不想处理 IO 包装器,所以我能以什么方式做到这一点?
对不起,函数giveRandomElement :: Int返回一个不同的随机数,每次调用它的时候是不是引用透明,所以Haskell的纯度也不会允许你做你喜欢的事情。
我认为使用随机值是了解 monad 的绝佳机会。MonadRandom有一个非常灵活的接口来编写结果是随机的函数:
die :: (MonadRandom m) => m Int
die = getRandomR (1, 6)
rollDice :: (MonadRandom m) => m (Int, Int)
rollDice = do
x <- die
y <- die
return (x, y)
-- Your example
giveRandomElement :: (MonadRandom m) => m Int
giveRandomElement = do
let n = length tetrominoes
i <- getRandomR (0, n-1)
return (giveList !! i)
Run Code Online (Sandbox Code Playgroud)
这个 monad 的实现将通过你的随机函数为你线程化随机状态。甚至还有一个instance MonadRandom IO,它可以让你写
main :: IO ()
main = do
x <- giveRandomElement
print x
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
565 次 |
| 最近记录: |