Reputation: 17
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
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 Int
s with a seeded pseudo-random generator:
Prelude System.Random Data.List> shuffleStack (mkStdGen 0) [1,4,2,5]
[4,5,2,1]
Upvotes: 3