在Haskell中获取随机列表项 [英] Get a random list item in Haskell

查看:75
本文介绍了在Haskell中获取随机列表项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

>审核此SO问题后,我尝试根据randomIO生成器的返回结果使用随机数生成器返回随机列表项.

After reviewing this SO question I am trying to use the random number generator to return a random list item based on the return of the randomIO generator.

完整代码:

module Randomizer where
import System.IO
import System.Random

data Action = Create | Destroy
  deriving (Enum, Eq, Show)

type History = [Action]

-- | this looks at three sets of histories, and returns an appropriate Action
type ThreeHistoryDecisionMaker = History -> History -> History -> Action

allThreeDecisionMakers :: [ThreeHistoryDecisionMaker]
allThreeDecisionMakers = [decision1, decision2, decision3, decision4, decision5]

chooseRandomDecision :: [ThreeHistoryDecisionMaker] -> Int -> Strategy3P
chooseRandomDecision = allThreeDecisionMakers !! randomIO(0,4) 

但是我遇到以下错误:

special_program1.hs:249:16:
    Couldn't match type ‘Action’
                  with ‘History -> History -> History -> Action’
    Expected type: [[ThreeHistoryDecisionMaker] -> Int -> ThreeHistoryDecisionMaker]
      Actual type: [ThreeHistoryDecisionMaker]
    In the first argument of ‘(!!)’, namely ‘allThreeDecisionMakers’
    In the expression: all3PStrategies !! randomIO (0, 4)

special_program1.hs:249:35:
    Couldn't match expected type ‘(t0, t1) -> Int’
                with actual type ‘IO a0’
    The function ‘randomIO’ is applied to one argument,
    but its type ‘IO a0’ has none
    In the second argument of ‘(!!)’, namely ‘randomIO (0, 4)’
    In the expression: all3PStrategies !! randomIO (0, 4)

为什么第一个错误块希望包含其中的所有内容的列表?

Why is the first error block wanting to expect a list of everything inside it?

第二个代码块是什么意思?

What does the second code block mean?

推荐答案

randomIO不是 一个随机函数".这样的事情在Haskell中不存在,它不是参照透明的.相反,顾名思义,这是 IO操作,它可以产生随机值.用IO操作索引列表是没有意义的,!! randomIO(0,4)是不可能的. (这也是不可能的,因为另一个原因:randomIO创建无限值,如果需要指定(0,4)范围,则需要randomRIO("Range参数"带有R).)

randomIO is not a "random function". Such a thing doesn't exist in Haskell, it wouldn't be referentially transparent. Instead, as the name suggests, it's an IO action which can yield a random value. It makes no sense to index a list with an IO action, !! randomIO(0,4) isn't possible. (It's impossible also for another reason: randomIO creates unlimited values, you want randomRIO (with an R for "range parameter") if you need to specify a (0,4) range.)

您需要做些什么才能使操作获得收益的价值:好吧,单子!如果您还没有学习有关这些的理论,那就没关系.随机索引器可能会这样:

What you need to to do to get the value yielded by the action: well, monads! If you haven't learned the theory about those yet, never mind. A random-indexer could look thus:

atRandIndex :: [a] -> IO a  -- note that this is gives itself an IO action
atRandIndex l = do
    i <- randomRIO (0, length l - 1)
    return $ l !! i

我建议您实际上使用该功能来实现您的任务.

I suggest you actually use that function to implement your task.

但是回到您发布的代码...还有更多问题.如果用两个参数指定chooseRandomDecision的类型,则实际上需要根据这些参数定义它!但是您的定义根本不接受任何参数,它仅使用全局定义的列表allThreeDecisionMakers(不必在类型中声明使用全局变量).

But back to the code you posted... there's more problems. If you specify the type of chooseRandomDecision with two arguments, then you need to actually define it as a function of these arguments! But your definition doesn't accept any arguments at all, it merely uses the globally-defined list allThreeDecisionMakers (use of global variables never needs to be stated in the type).

此外,如果您要从THDMaker列表中进行选择,那么生成的元素也将具有该类型,还有什么呢!因此,除非Strategy3P仅仅是History -> History -> History -> Action的另一个同义词,否则即使您将其包含在正确的monad中也不会这样做.

Moreover, if you're choosing from a list of THDMakers, then the resulting element will also have that type, what else! So unless Strategy3P is simply another synonym of History -> History -> History -> Action, this won't do as a result, even if you contain it in the right monad.

这篇关于在Haskell中获取随机列表项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆