ergoforce
ergoforce

Reputation: 17

How can I get 8-x random values in Haskell?

I'm trying to make a function worp that returns 2 lists of integers.

Where the first list of integers is the result of 8 minus the length of the input list, dice throws.

And the second list is the input list.

This is my code:

import System.Random

worp :: [Int] -> [[IO Int]]
worp d = [werpDobbelstenen (8-length d),d]

werpDobbelstenen :: Int -> [IO Int]
werpDobbelstenen 0 = []
werpDobbelstenen x = randomRIO (1,6):werpDobbelstenen x-1

Im getting this error:

System.IO> :load "X:\\haskell\\dobbel.hs"
ERROR file:.\dobbel.hs:17 - Instance of Num [IO Int] required for definitio of werpDobbelstenen

Upvotes: 0

Views: 71

Answers (1)

chepner
chepner

Reputation: 532003

First, I would return an IO [Int] value for simplicity:

import Control.Monad  -- replicateM
import System.Random  -- randomRIO

werpDobbelstenen :: Int -> IO [Int]
werpDobbelstenen n = replicateM n (randomRIO (1,6))

Now, define your worp more simply, as one that simply takes a list of Int and returns the desired pair of lists.

worp' :: [Int] -> ([Int], [Int])
worp' d = (d, map (\x -> x - length d) d)

And finally, you can simply map worp over the result of werpDobbelstenen to get an IO ([Int], [Int]) value.

worp :: Int -> IO ([Int], [Int])
worp n = fmap worp' (werpDobbelstenen n)

After a little more thinking, I think this is what you want:

import Control.Monad  -- replicateM
import System.Random  -- randomRIO

werpDobbelstenen :: Int -> IO [Int]
werpDobbelstenen n = replicateM n (randomRIO (1,6))

worp' :: [Int] -> IO ([Int],  [Int])
worp' d = let n = 8 - length d
          in do d' <- werpDobbelstenen n
                return (d, d')

worp :: Int -> IO ([Int], [Int])
worp n = werpDobbelstenen n >>= worp'

>>> worp 6
([4,1,2,5,6,4],[1,2])

In this case, the second value of the tuple is always an empty list for n >= 8. You may want to do something different for values larger than 8.

Upvotes: 1

Related Questions