Haskell QuickCheck Unique Random Number Generation - haskell

Does anyone know exactly how to define a generator in Haskell using QuickCheck such that chosen elements are picked only ONCE?
I've gotten as far as realizing that I might need a "Gen (Maybe Positive)" generator, but of course that will generate number with repetition. I want it so that the numbers chosen are picked without repetition. In the instance when a number is returned I want Just returned and in the instance where the randoms are all exhausted I want Gen Nothing returned.
Thanks,
Mark

You can't. Look at the definition of Gen. There's no way for it to carry any state about what has been picked so far. Given the same random generator and size limit it must always generate the same result. You can however write a Eq a => Gen [a] that generates a list of values with no repetitions. A simple (but somewhat naive) one would be something like this.
uniques :: Eq a => Gen a -> Gen [a]
uniques gen = fmap nub $ listOf gen

QuickCheck is generally for randomized testing, not exhaustive testing. There are a few great libraries that do handle exhaustive testing -- look at smallcheck and lazysmallcheck.

You can use permutations (in module Data.List) for this.
Here is the function signature for permutations:
permutations :: [a] -> [[a]]
As you can see, it returns a list of lists. Here is a little example (using GHCi 7.0.4):
> permutations [1..3]
[[1,2,3],[2,1,3],[3,2,1],[2,3,1],[3,1,2],[1,3,2]]
So you could do something like:
prop_unique_elements = forAll (elements (permutations [1..3])) $ \x -> foo == bar
I haven't tested that so it will need some massaging, but I hope it conveys the point clearly. Good luck.

Related

Unit testing IO Int and similar in Haskell

From Ninety-Nine Haskell Problems:
Question 23: Extract a given number of randomly selected elements from a list.
This is a partial solution. For simplicity, this code just selects one element from a list.
import System.Random (randomRIO)
randItem :: [a] -> IO a
randItem xs = do
i <- randomRIO (0,length xs - 1)
return $ xs !! i
so randItem [1..10] would return an IO Int that corresponds to (but does not equal) some Int from 1 through 10.
So far, so good. But what kind of tests can I write for my randItem function? What relationship--if any--can I confirm between the input and output?
I can use the same logic as the above function to produce m Bool, but I cannot figure out how to test for m Bool. Thank you.
There's a couple of things you can do. If you're using QuickCheck, you could write the following properties:
The length of the returned list should be equal to the input length.
All elements in the returned list should be elements of the list of candidates.
Apart from that, the beauty of Haskell's Random library is that (as most other Haskell code) it's deterministic. If, instead of basing your implementation on randomRIO, you could base it on randomR or randomRs. This would enable you to pass some known RandomGen values to some deterministic unit test cases (not QuickCheck). These could serve as regression tests.
I've now published an article about the above approach, complete with source code.

Get elements with odd length in a Haskell list of strings

I have a list of strings in Haskell and I need to get those elements with odd length in another list. How can this be done using higher order functions like foldr, foldl, foldr1, foldl1, filter, map, and so on? I will very much appreciate your help. Can list comprehension be used in this case?
It seems that you are aware that filter exists (since you've mentioned), but perhaps are uncertain how it works. If you're trying to extract a specific subset of a list, this seems to be the right path. If you look at its type-signature, you'll find it's pretty straight-forward:
(a -> Bool) -> [a] -> [a]
That is, it takes a function that returns True or False (i.e. true to contain in the new set, false otherwise) and produces a new list. Similarly, Haskell provides a function called odd in Prelude. It's signature looks as follows:
Integral a => a -> Bool
That is, it can take any Integral type and returns True if it is odd, false otherwise.
Now, let's consider a solution:
filter odd [1..10]
This will extract all the odd numbers between [1,10].
I noticed you mentioned list comprehensions. You probably do not want to use this if you are already given a list and you are simply filtering it. However, a list comprehension would be a perfectly acceptable solution:
[x | x <- [1..10], odd x]
In general, list comprehensions are used to express the generation of lists with more complicated constraints.
Now, to actually answer your question. Since we know we can filter numbers, and if we're using Hoogle searching for the following type (notice that String is simply [Char]):
[a] -> Int
You will see a length function. With some function composition, we can quickly see how to create a function which filters odd length. In summary, we have odd which is type Int -> Bool (in this case) and we have length which is [a] -> Int or-- specifically-- String -> Int. Our solution now looks like this:
filter (odd . length) ["abc","def","eh","123","hm","even"]
Here ya go.
getOddOnes = filter . flip (foldr (const (. not)) id) $ False
Note: if you turn this in for your homework, you'd best be prepared to explain it!

Test a function with a list of bounded value with quickCheck

I need to test some function with quickCheck do validate these function.
I need to send value in the range 1 to 40 to the function but I'm very beginner with quickCheck and it's modificator.
I tried :
myTestFunction (x,y,z) (Positive div) = ....
with
quickCheck myTestFunction
div remain positive but can take very high value (and I don't want)
What is the correct way to give div random value in the range a to b ?
Is it also possible to impose a list of value (non random) to quickCheck ?
You need to combine two parts. The first is generation—you need to write a QuickCheck random generator that outputs numbers in your desired range. Happily, we can do this with a built-in function:
choose :: Random a => (a, a) -> Gen a
Next, we need to specify a property that uses this custom generator. This is where the property combinators really come in handy. Again, the function we want is the first one in the documentation section:
forAll :: (Show a, Testable prop) => Gen a -> (a -> prop) -> Property
This lets us pass our custom generator in for a function parameter.
Putting all this together, the test case will look something like this:
prop_myTest (x, y, z) = forAll (choose (1, 40)) $ \ ndiv -> ...
The "prop_" naming scheme is conventionally used for QuickCheck tests. This will help people quickly understand what's going on in your code and is used by some test frameworks, so it's a good habit to get into now.

most frequently occurring string (element) in a list?

I have made a function which prints every possible subsequence of a string. Now I need to make a function which prints the most common. Any ideas on where I can start. Not asking for fully coded functions just a place to start. Also, only using prelude functions (including base).
for example, if I enter "jonjo" my functions will return ["jonjo","jonj","jon","jo","j","onjo","onj"...] etc. The most common substring would be "jo".
In the case where there would be two or more most occurring substrings, only the longest would be printed. If still equal, any one of the substrings will suffice.
The problem as it is stated can be reduced to finding the most frequent character, since it is obvious that, for example, the first character in any "most frequent substring" will be AT LEAST as frequent as the substring itself.
I suggest you take a look at
sort :: Ord a => [a] -> [a]
from base Data.List
group :: Eq a => [a] -> [[a]]
from base Data.List
length :: [a] -> Int
from base Prelude, base Data.List
and
maximum :: Ord a => [a] -> a
from base Prelude, base Data.List
If you can really ony use prelude functions, then I suggest you implement these yourself, or design a datastructure to make this efficient, such as a trie.

Random-Pivot Quicksort in Haskell

Is it possible to implement a quicksort in Haskell (with RANDOM-PIVOT) that still has a simple Ord a => [a]->[a] signature?
I'm starting to understand Monads, and, for now, I'm kind of interpreting monads as somethink like a 'command pattern', which works great for IO.
So, I understand that a function that returns a random number should actually return a monadic value like IO, because, otherwise, it would break referential transparency. I also understand that there should be no way to 'extract' the random integer from the returned monadic value, because, otherwise, it would, again, break referential transparency.
But yet, I still think that it should be possible to implement a 'pure' [a]->[a] quicksort function, even if it uses random pivot, because, it IS referential transparent. From my point of view, the random pivot is just a implementation detail, and shouldn't change the function's signature
OBS: I'm not actually interested in the specific quicksort problem (so, I don't want to sound rude but I'm not looking for "use mergesort" or "random pivot doesn't increase performance in practice" kind of answers) I'm actually interested in how to implement a 'pure' function that uses 'impure' functions inside it, in cases like quicksort, where I can assure that the function actually is a pure one.
Quicksort is just a good example.
You are making a false assumption that picking the pivot point is just an implementation detail. Consider a partial ordering on a set. Like a quicksort on cards where
card a < card b if the face value is less but if you were to evaluate booleans:
4 spades < 4 hearts (false)
4 hearts < 4 spades (false)
4 hearts = 4 spades (false)
In that case the choice of pivots would determine the final ordering of the cards. In precisely the same way
for a function like
a = get random integer
b = a + 3
print b
is determined by a. If you are randomly choosing something then your computation is or could be non deterministic.
OK, check this out.
Select portions copied form the hashable package, and voodoo magic language pragmas
{-# LANGUAGE FlexibleInstances, UndecidableInstances, NoMonomorphismRestriction, OverlappingInstances #-}
import System.Random (mkStdGen, next, split)
import Data.List (foldl')
import Data.Bits (shiftL, xor)
class Hashable a where
hash :: a -> Int
instance (Integral a) => Hashable a where
hash = fromIntegral
instance Hashable Char where
hash = fromEnum
instance (Hashable a) => Hashable [a] where
hash = foldl' combine 0 . map hash
-- ask the authors of the hashable package about this if interested
combine h1 h2 = (h1 + h1 `shiftL` 5) `xor` h2
OK, so now we can take a list of anything Hashable and turn it into an Int. I've provided Char and Integral a instances here, more and better instances are in the hashable packge, which also allows salting and stuff.
This is all just so we can make a number generator.
genFromHashable = mkStdGen . hash
So now the fun part. Let's write a function that takes a random number generator, a comparator function, and a list. Then we'll sort the list by consulting the generator to select a pivot, and the comparator to partition the list.
qSortByGen _ _ [] = []
qSortByGen g f xs = qSortByGen g'' f l ++ mid ++ qSortByGen g''' f r
where (l, mid, r) = partition (`f` pivot) xs
pivot = xs !! (pivotLoc `mod` length xs)
(pivotLoc, g') = next g
(g'', g''') = split g'
partition f = foldl' step ([],[],[])
where step (l,mid,r) x = case f x of
LT -> (x:l,mid,r)
EQ -> (l,x:mid,r)
GT -> (l,mid,x:r)
Library functions: next grabs an Int from the generator, and produces a new generator. split forks the generator into two distinct generators.
My functions: partition uses f :: a -> Ordering to partition the list into three lists. If you know folds, it should be quite clear. (Note that it does not preserve the initial ordering of the elements in the sublists; it reverses them. Using a foldr could remedy this were it an issue.) qSortByGen works just like I said before: consult the generator for the pivot, partition the list, fork the generator for use in the two recursive calls, recursively sort the left and right sides, and concatenate it all together.
Convenience functions are easy to compose from here
qSortBy f xs = qSortByGen (genFromHashable xs) f xs
qSort = qSortBy compare
Notice the final function's signature.
ghci> :t qSort
qSort :: (Ord a, Hashable a) => [a] -> [a]
The type inside the list must implement both Hashable and Ord. There's the "pure" function you were asking for, with one logical added requirement. The more general functions are less restrictive in their requirements.
ghci> :t qSortBy
qSortBy :: (Hashable a) => (a -> a -> Ordering) -> [a] -> [a]
ghci> :t qSortByGen
qSortByGen
:: (System.Random.RandomGen t) =>
t -> (a -> a -> Ordering) -> [a] -> [a]
Final notes
qSort will behave exactly the same way for all inputs. The "random" pivot selection is. in fact, deterministic. But it is obscured by hashing the list and then seeding a random number generator, making it "random" enough for me. ;)
qSort also only works for lists with length less than maxBound :: Int, which ghci tells me is 9,223,372,036,854,775,807. I thought there would be an issue with negative indexes, but in my ad-hoc testing I haven't run into it yet.
Or, you can just live with the IO monad for "truer" randomness.
qSortIO xs = do g <- getStdGen -- add getStdGen to your imports
return $ qSortByGen g compare xs
ghci> :t qSortIO
qSortIO :: (Ord a) => [a] -> IO [a]
ghci> qSortIO "Hello world"
" Hdellloorw"
ghci> qSort "Hello world"
" Hdellloorw"
In such cases, where you know that the function is referentially transparent, but you can't proof it to the compiler, you may use the function unsafePerformIO :: IO a -> a from the module Data.Unsafe.
For instance, you may use unsafePerformIO to get an initial random state and then do anything using just this state.
But please notice: Don't use it if it's not really needed. And even then, think twice about it. unsafePerformIO is somewhat the root of all evil, since it's consequences can be dramatical - anything is possible from coercing different types to crashing the RTS using this function.
Haskell provides the ST monad to perform non-referentially-transparent actions with a referentially transparent result.
Note that it doesn't enforce referential transparency; it just insures that potentially non-referentially-transparent temporary state can't leak out. Nothing can prevent you from returning manipulated pure input data that was rearranged in a non-reproducible way. Best is to implement the same thing in both ST and pure ways and use QuickCheck to compare them on random inputs.

Resources