damri
damri

Reputation: 17

Haskell ERROR - Ambiguous type variable `b0' arising from a use of `randoms'

I am new to haskell and am trying to make a function which will shuffle a list of objects. However, I keep getting ambiguous type errors, I also got one from the 'cmp' function as well.

cmp :: Ord b => (a, b) -> (a, b) -> Ordering
cmp (x1,y1) (x2,y2) = compare y1 y2 

--shuffleStack is giving me ambiguous type errors when running, one for randoms and one for cmp
shuffleStack :: StdGen -> [a] -> [a]
shuffleStack g domSet = [x | (x,y) <- sortBy cmp (zip domSet (randoms g))]

--This function nearly does the same thing but doesn't give any errors
test g domSet = sortBy cmp (zip domSet (randoms g))

Does anybody know what I am doing wrong? Thanks!

Upvotes: 1

Views: 84

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477240

The problem is that because you later remove the second element of the 2-tuples, this thus means that the type of the random elements b, is not in the signature anymore, and thus can be anything.

You should give it a hint what type to use, for example an Int:

shuffleStack :: StdGen -> [a] -> [a]
shuffleStack g domSet = [x | (x,y) <- sortBy cmp (zip domSet (randoms g :: [Int]))]

Note that you can make use of sortOn :: Ord b => (a -> b) -> [a] -> [a]:

import Data.List(sortOn)

shuffleStack :: StdGen -> [a] -> [a]
shuffleStack g domSet = [x | (x,y) <- sortOn snd (zip domSet (randoms g :: [Int]))]

You can also perform a mapping to get rid of the second item of the 2-tuples. We can also swap the order of the items of the 2-tuple to eliminate the explicit domSet parameter:

import Data.List(sortOn)

shuffleStack :: StdGen -> [a] -> [a]
shuffleStack g = map snd . sortOn fst . zip (randoms g :: [Int])

For example we can shuffle a list of Ints with a seeded pseudo-random generator:

Prelude System.Random Data.List> shuffleStack (mkStdGen 0) [1,4,2,5]
[4,5,2,1]

Upvotes: 3

Related Questions