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.
Full Code:
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)
But I get the following errors:
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
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.
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).
Moreover, if you're choosing from a list of THDMaker
s, 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With