Reputation: 1126
My goal is to get a list of N random items taken from an input list and see the result in GHCI. I decided to shuffle the input list, then take the first N elements from it (i.e. slice first elements). I am using shuffle
function from random-fu module Data.Random.List.
Here's the code I currently have and at least it can be compiled
import Data.Random
import Data.Random.List
rndSelect :: [a] -> Int -> RVar [a]
rndSelect l n
= do
l' <- shuffle l;
return $ take n l'
But when I run rndSelect "abcdefg" 3
in GHCI prompt, I get the following error:
<interactive>:1:1: error:
• No instance for (Show (RVar [Char]))
arising from a use of ‘print’
• In a stmt of an interactive GHCi command: print it
I think I know what it means. RVar
doesn't derive Show
. I guess I should modify my function so that it gets shuffled RVar[a]
and then somehow take a list of the first N elements and convert it to IO action.
Here's one of my failed attempts:
rndSelect :: [a] -> Int -> IO ()
rndSelect l n
= do
l' <- shuffle l;
l'' <- take n l'
s <- runRVar l'' StdRandom
putStrLn s
I know, that it is messed up and raises errors on top of errors. I am beginner in Monads, "do" blocks and things like that in Haskell
I would be glad if someone help me to fix my approach, but if you know alternative way to achieve my goal, I will be happy to see it as well. Thank you very much!
Upvotes: 1
Views: 106
Reputation: 120741
Your rndSelect :: [a] -> Int -> RVar [a]
is perfectly fine, but it should be obvious that the resulting RVar [a]
can't really be shown. After all, this is a probability distribution. Such distributions “contain” in general infinitely many possible outcomes. All you can hope to do is to show samples from the distribution. Since GHCi allows you to do IO, it's easy to obtain samples right there:
*Main> sample $ rndSelect "abcdefg" 3
"def"
*Main> sample $ rndSelect "abcdefg" 3
"ecb"
*Main> sample $ rndSelect "abcdefg" 3
"fbc"
*Main> :m +Control.Monad
*Main Control.Monad> sample . replicateM 20 $ rndSelect "abcdefg" 3
["gef","adf","cga","bfd","eab","bgd","gdf","abg","egc","bda","ceb","fbd","agb","egc","acb","bga","gbd","edb","egb","egd"]
Upvotes: 2