Beginner Haskell, quickcheck generator - haskell

I want to generate an increasing number of lists i.e.
prelude>sample' incList
[[],[19],[6,110],[24,67,81]....]
How should I use vectorOf?
incList:: Gen [Integer]
incList=
do x<-vectorOf [0..] arbitrary
return x
I cant think of a way to just take out the first number from the list one at a time :/ Maybe something with fmap take 1, I dunno..

I think you here aim to do too much at once. Let us first construct a generator for a random list of Ordered objects with a given length in ascending order:
import Data.List(sort)
incList :: (Arbitrary a, Ord a) => Int -> Gen [a]
incList n = fmap sort (vectorOf n arbitrary)
Now we can construct a Generator that generates an endless list of lists by each time incrementing the size with one:
incLists :: (Arbitrary a, Ord a) => Gen [[a]]
incLists = mapM incList [0..]
We can then generate values from this Generator with generate :: Gen a -> IO [a]:
Prelude File> generate incLists :: IO [[Int]]
[[],[-19],[6,25],[-19,-14,15],[-4,6,20,28],[-23,-19,-6,-1,22],[-29,-21,-13,-9,-9,15],[-23,-15,-4,3,3,27,27],[-29,-29,-26,-25,18,19,23,27],[-24,-23,-16,-14,0,13,17,17,23],[-29,-15,-12,-4,-1,1,2,20,22,26],[-26,-24,-22,-16,-12,5,5,10,11,25,29],[-29,-28,-20,-14,-9,-7,-3,14,15,20,26,28],...]

Related

How to generate strings drawn from every possible character?

At the moment I'm generating strings like this:
arbStr :: Gen String
arbStr = listOf $ elements (alpha ++ digits)
where alpha = ['a'..'z']
digits = ['0'..'9']
But obviously this only generates strings from alpha num chars. How can I do it to generate from all possible chars?
Char is a instance of both the Enum and Bounded typeclass, you can make use of the arbitraryBoundedEnum :: (Bounded a, Enum a) => Gen a function:
import Test.QuickCheck(Gen, arbitraryBoundedEnum, listOf)
arbStr :: Gen String
arbStr = listOf arbitraryBoundedEnum
For example:
Prelude Test.QuickCheck> sample arbStr
""
""
"\821749"
"\433465\930384\375110\256215\894544"
"\431263\866378\313505\1069229\238290\882442"
""
"\126116\518750\861881\340014\42369\89768\1017349\590547\331782\974313\582098"
"\426281"
"\799929\592960\724287\1032975\364929\721969\560296\994687\762805\1070924\537634\492995\1079045\1079821"
"\496024\32639\969438\322614\332989\512797\447233\655608\278184\590725\102710\925060\74864\854859\312624\1087010\12444\251595"
"\682370\1089979\391815"
Or you can make use of the arbitrary in the Arbitrary Char typeclass:
import Test.QuickCheck(Gen, arbitrary, listOf)
arbStr :: Gen String
arbStr = listOf arbitrary
Note that the arbitrary for Char is implemented such that ASCII characters are (three times) more common than non-ASCII characters, so the "distribution" is different.
Since Char is an instance of Bounded as well as Enum (confirm this by asking GHCI for :i Char), you can simply write
[minBound..maxBound] :: [Char]
to get a list of all legal characters. Obviously this will not lead to efficient random access, though! So you could instead convert the bounds to Int with Data.Char.ord :: Char -> Int, and use QuickCheck's feature to select from a range of integers, then map back to a character with Data.Chra.chr :: Int -> Char.
When we do like
λ> length ([minBound..maxBound] :: [Char])
1114112
we get the number of all characters and say Wow..! If you think the list is too big then you may always do like drop x . take y to limit the range.
Accordingly, if you need n many random characters just shuffle :: [a] -> IO [a] the list and do a take n from that shuffled list.
Edit:
Well of course... since shuffling could be expensive, it's best if we chose a clever strategy. It would be ideal to randomly limit the all characters list. So just
make a limits = liftM sort . mapM randomRIO $ replicate 2 (0,1114112) :: (Ord a, Random a, Num a) => IO [a]
limits >>= \[min,max] -> return . drop min . take max $ ([minBound..maxBound] :: [Char])
Finally just take n many like random Chars like liftM . take n from the result of Item 2.

Haskell maximumBy for Ord instances

I keep finding myself wanting a function for this, and I always need to implement it myself, but I feel like there must be a built-in for it.
Basically, what I want is sort of halfway between maximum and maximumBy.
maximum takes a list of Ord values and returns the maximum. This is O(n).
maximum :: (Ord a) => [a] -> a
maximumBy takes a list of non-Ord values and a sort function that provides an ordering for them, and computes the maximum using that function. This is O(nlogn) (or whatever the complexity is for a sort).
maximumBy :: (a -> a -> Ordering) -> [a] -> a
I want a maximumBy that takes a list of values of type a and a function that returns Ord values for a values, and computes the maximum a using the Ord values. This would be O(n) because it only needs to keep track of the maximum as it goes along. This is what that signature would be:
maximumBy' :: (Ord b) => (a -> b) -> [a] -> a
And this is my rough implementation:
maximumBy' func list = foldl1' (\max i -> let (maxby, iby) = (func max, func i) in if iby > maxby then i else max) list
Is there such a function built-in, or perhaps an easy way to write this using existing built-ins?
First of all you make a claim that is wrong:
maximumBy takes a list of non-Ord values and a sort function that provides an ordering for them, and computes the maximum using that function. This is O(nlogn).
No sorting has to be done to calculate the maximum element. An ordering relation has to be reflexive, anti-symmetric and transitive, and therefore one can simply alsways hold the maximum thus far, and use the custom comparison to check whether the new item is greater.
Furthermore you can construct you maximumBy' function as:
maximumBy' f = maximumBy (compare `on` f)
I think what you are looking for is easily expressed using Data.Ord.comparing:
Instead of using your maximumBy' function:
maximumBy' head ["abc", "def", "geh"]
you can build a comparator with comparing and give that to the usual maximumBy:
maximumBy (comparing head) ["abc", "def", "geh"]
And as Willem Van Onsem says in another answer, you are incorrect to be concerned about the cost of maximumBy: it does not sort the list.
That function is defined the tip-lib package as
maximumOn :: (Foldable f, Ord b) => (a -> b) -> f a -> b
The general idea has also been adopted in recent base, with
sortOn :: Ord b => (a -> b) -> [a] -> [a]
Note that thanks to laziness, you can use
maximumOn :: Ord b => (a -> b) -> [a] -> b
maximumOn f = head . sortOn f
and get the same asymptotic performance as a manual implementation.
I don't know any built-in function that does what you want, but you can really simplify your implementation of maximumBy'.
You could use on for example:
import Data.Function (on)
maximumBy' :: Ord b => (a -> b) -> [a] -> a
maximumBy' f = maximumBy (compare `on` f)
In fact, this definition is so simple you could use it as-is, without defining maximumBy' at all.

Maximum of IO(Int) list

I have the following sample code
let x = [return 1::IO(Int), return 2::IO(Int)]
So x is a list of IO(Int)s.
maximum is a function which returns the maximum of a list, if the things in the list are Ords.
How do I "map" maximum to run on this list of IO(Int)s?
First sequence the array into IO [Int] and then run maximum on it using liftM:
liftM maximum (sequence yourList) :: IO Int
The key point here is that you cannot compare IO actions, only the values
that result from those actions. To perform the comparison, you have to perform
those actions to get back a list of the results. Fortunately, there is
a function that does just that: sequence :: (Monad m) => [m a] -> m [a].
This takes a list of actions and performs them in order to produce an action
that gives a list of results.
To compute the maximum, you would do something like
x = [return 1::IO(Int), return 2::IO(Int)]
...
biggest = maximum `fmap` sequence x :: IO [Int]

Composing Haskell filters

I am converting the zxcvbn password strength algorithm to Haskell.
I have two functions that check for all characters being ASCII and that a brute force attack is possible:
filterAscii :: [String] -- ^terms to filter
-> [String] -- ^filtered terms
filterAscii = filter $ all (\ chr -> ord chr < 128)
and
filterShort :: [String] -- ^terms to filter
-> [String] -- ^filtered terms
filterShort terms = map fst $ filter long $ zip terms [1..]
where long (term, index) = (26 ^ length term) > index
I composed these into a single function:
filtered :: [String] -- ^terms to filter
-> [String] -- ^filtered terms
filtered = filterAscii . filterShort
I now have need to compose these with a third filter to check if the terms are not null:
filter (not . null) terms
It has occurred to me that I am creating a chain of filters and that it would make more sense to create a single function that takes a list of filter functions and composes them in the order given.
If I recall from my reading, this is a job for an applicative functor, I believe. Can I use applicatives for this?
I am not sure how to handle the filterShort function where I need to zip each item with its one-based index before filtering.
You can use the Endo wrapper from Data.Monoid to get a monoid instance that will allow you to use mconcat like so:
Prelude> :m + Data.Monoid
Prelude Data.Monoid> :t appEndo $ mconcat [Endo filterAscii, Endo filterShort]
appEndo $ mconcat [Endo filterAscii, Endo filterShort] :: [String] -> [String]
In other words, you want :
filters :: [a -> Bool] -> [a] -> [a]
filters fs = filter (\a -> and $ map ($ a) fs)
But you should also know that a pipeline of filters is very likely to be optimized by GHC (as far as I know) anyway. So it may not be worth it to create this function. Note that there will be some problems with your filterShort since it's not a pure filter.

Generating a list of random numbers with foldM

I want to generate a list of random numbers, where the range of each random number is determined by elements of a provided list. I thought I had something that made sense, but I get errors I don't understand :(
Here's what I have:
useRNG nums min = do
generator <- get
let (val, generator') = randomR (min, 51) generator
put generator'
return $ val : nums
foldM useRNG [] [0 .. 50]
Can anyone help me out?
The problem is that useRNG can generate all kinds of numbers (any instance of Random), and work in all kinds of monads (any state monad whose state is an instance of RandomGen), as can be seen from its inferred type signature:
GHCi> :t useRNG
useRNG
:: (MonadState s m, RandomGen s, Random a, Num a) =>
[a] -> a -> m [a]
...but when you use it, you haven't specified which concrete types you actually want.
If you disambiguate with a type signature:
test :: State StdGen [Int]
test = foldM useRNG [] [0 .. 50]
then it works fine. You could also accomplish this by putting a type signature on useRNG:
useRNG :: [Int] -> Int -> State StdGen [Int]
Now, you might be thinking: if useRNG works fine with all these types, why can't test too? The answer is the monomorphism restriction, which is fairly arcane and not well-liked by many Haskell users. You can avoid it by either putting
{-# LANGUAGE NoMonomorphismRestriction #-}
at the top of your file, or giving test an explicit type signature:
test :: (RandomGen g, Random a, Num a, Enum a, MonadState g m) => m [a]
You can find out the correct type signature with GHCi:
GHCi> :t foldM useRNG [] [0 .. 50]
foldM useRNG [] [0 .. 50]
:: (MonadState s m, RandomGen s, Random b, Num b, Enum b) => m [b]
(I wrote the explicit type signature before checking with GHCi, which is why mine is slightly different.)
However, this type signature is a little too polymorphic for practical uses — you'll basically be putting the ambiguity off until you actually use the result — so I'd suggest specifying it more concretely in this instance. You could, for instance, keep test generic over the type of random number without the needless polymorphism over the state monad and generator type:
test :: (Random a, Num a, Enum a) => State StdGen [a]
You might also want to consider using MonadRandom, which wraps all the standard random number generation facilities in a state monad-based interface so you don't have to :)

Resources