Generating a lists of a specific length with Haskell's QuickCheck - haskell

-- 3 (find k"th element of a list)
element_at xs x = xs !! x
prop_3a xs x = (x < length xs && x >= 0) ==> element_at xs (x::Int) == (xs !! x::Int)
When prop_3a is ran through QuickCheck, it gives up, because it won't generate long enough lists.
How can I write a generator that will generate lists with length longer than the random integer?

hammar's answer is perfectly adequate for the problem. But for the sake of answering the precise question asked, I couldn't help but investigate a bit. Let's use forAll.
prop_bang x = x >= 0 ==> forAll (listLongerThan x) $ \xs ->
element_at xs x == xs !! x
So now we need a function, listLongerThan :: Int -> Gen [Int]. It takes a length, x, and produces a generator which will produce lists of length greater than x.
listLongerThan :: Int -> Gen [Int]
listLongerThan x = replicateM (x+1) arbitrary
It's rather straightforward: we simply take advantage of the Monad instance of Gen. If you run quickCheck prop_bang, you'll notice it starts taking quite a long time, because it begins testing absurdly long lists. Let's limit the length of the list, to make it go a bit faster. Also, right now listLongerThan only generates a list that is exactly x+1 long; let's mix that up a bit, again utilizing the Monad instance of Gen.
prop_bang =
forAll smallNumber $ \x ->
forAll (listLongerThan x) $ \xs ->
element_at xs x == xs !! x
smallNumber :: Gen Int
smallNumber = fmap ((`mod` 100) . abs) arbitrary
listLongerThan :: Int -> Gen [Int]
listLongerThan x = do
y <- fmap (+1) smallNumber -- y > 0
replicateM (x+y) arbitrary
You can use sample smallNumber or sample (listLongerThan 3) in ghci to make sure it is generating the correct stuff.

How about going the other way? First we let QuickCheck pick a list and then we constrain what indices we allow. This works, and does not throw away any test cases.
prop_3a (NonEmpty xs) = forAll (choose (0, length xs - 1)) $ \i ->
element_at xs i == (xs !! i :: Int)
Here, I use forAll to use a specific generator for the indices, in this case using choose which picks an element from a specified range, and I also use the NonEmptyList type to ensure that we don't try to index into an empty list.

This works:
import Test.QuickCheck
element_at :: [a] -> Int -> a
element_at xs i = xs !! i
prop_3a :: [Int] -> Int -> Property
prop_3a xs i = (i >= 0) ==> (length xs > i) ==> element_at xs i == xs !! i
However, the problem with this is that a lot of sample values are discarded. You could use things like Positive to help with ensuring that the index is valid.
If you want to be more complex, you can use more newtype wrappers to try and generate values of sufficient length (possibly using sized, or generate the list and the index together: generate the list, and then generate the index based upon the length of the list).

Related

Haskell - How to traverse through a list and reverse elements

I am having trouble locating documentation on simple operations in Haskell.
I have a list of lists (:: [[a]]) and I need to reverse all of the element lists x where length x >= 2.
So far I haven't found anything on:
How to traverse the lists
How would I find the length of the element. There is the length function I can use, but I haven't got an idea how to use it.
I did find the reverse function for lists, though I had trouble finding it.
If any help on those individual implementation, it would be greatly appreciated. I can piece them together.
I need to reverse all of the element lists x where length x >= 2
You can totally ignore the length x >= 2 part, since if the length of a list is 0 or 1, reversing it has no effect: there's no way to tell whether you reversed it or not, so you might as well just reverse all lists, for uniformity.
Given that, this is super simple: you just need to map reverse over the list of lists, reversing each one in turn:
reverseEach :: [[a]] -> [[a]]
reverseEach = map reverse
> reverseEach [[1,2,3],[4],[5,6,7,8]]
[[3,2,1],[4],[8,7,6,5]]
And as other answers suggest, you can afford to generalize a little bit:
reverseEach :: Functor f => f [a] -> f [a]
reverseEach = fmap reverse
> reverseEach [[1,2,3],[4],[5,6,7,8]]
[[3,2,1],[4],[8,7,6,5]]
how to traverse the lists.
There are several sequence functions, from the more basic fmap, which maps a single function over a list, to foldr, which folds a list structure around a binary operation (for summing a list or similar operations) to the sequence/traverse operations, which carry monadic or applicative effects.
How would I find the length of the element. There is the length function I can use, but I haven't got an idea how to use it.
There is a length function; you use it like any other function. length xs, where xs is a list. If you still aren't certain how to do that, I would suggest starting slower with a Haskell tutorial.
And I have this to reverse the list, But i think i have that now.
There is a reverse function. If you don't want to use the built-in one (or if you want to do it yourself for educational purposes), you could build an efficient reverse function with an accumulator.
reverse' :: [a] -> [a]
reverse' xs = doReverse xs []
where doReverse [] ys = ys
doReverse (x:xs) ys = doReverse xs (x:ys)
Solution:
conditionallyReverse :: [[a]] -> [[a]]
ConditionallyReverse listOfLists= fmap f listOfLists
where
f list
| length list >= 2 = reverse x
| otherwise = x
We apply the function f to each element of the listOfLists by supplying f as the first argument to fmap and the listOfLists as the second argument. The function f transforms a list based on the condition length list >= 2. If the condition holds, the list is reversed, otherwise the original list is returned.
Absurd over-generalization:
Every Traversable instance supports a horrible hack implementing reverse. There may be a cleaner or more efficient way to do this; I'm not sure.
module Rev where
import Data.Traversable
import Data.Foldable
import Control.Monad.Trans.State.Strict
import Prelude hiding (foldl)
fill :: Traversable t => t b -> [a] -> t a
fill = evalState . traverse go
where
go _ = do
xs <- get
put (drop 1 xs)
return (head xs)
reverseT :: Traversable t => t a -> t a
reverseT xs = fill xs $ foldl (flip (:)) [] xs
reverseAll :: (Functor f, Traversable t) => f (t a) -> f (t a)
reverseAll = fmap reverseT
In terms of folds:
reverse = foldl (\ acc x -> x : acc) []
length = foldl' (\ n _ -> n + 1) 0
map f = foldr (\ x xs -> f x : xs)
letting
mapReverse = map (\ xs -> if length xs >= 2 then reverse xs else xs)
But length is a costly O(n), and reverse [x] = [x]. I would use
map reverse [[1,2,3],[4],[]] == [[3,2,1],[4],[]]
where (map reverse) :: [[a]] -> [[a]]. map reverse isn't basic enough to justify an own name binding.

Dividing evens of a list by two

halveEvens :: [Int] -> [Int]
halveEvens xs = [if xs == even then 'div' 2 xs | x<-xs]
Hey I'm trying to write down some code in haskell which will take the evens from a list and divide them by two. I am really new to this, so I am having some trouble. Is there anyone who could put me on the right track? I want to achieve this using list comprehension!
In your function xs is a list, even is a function that checks if Integral is even.
To use functions like operators, you enclose it in back quotes like this : x `div` 2.
halveEvens :: [Int] -> [Int]
halveEvens = map halveOneEven
halveOneEven :: Int -> Int
halveOneEven x = if (even x) then (x `div` 2) else x
Using list comprehension with a guard after a comma:
halveEvens xs = [x `div` 2 | x<-xs, even x]
You could read it as a mathematical definition: take all x values from xs that are even, and collect the result of dividing them into a list. In ghci you can use :t to check the types and make them match (xs is of type [Int], x is Int, and even is (Integral a) => a -> Bool).

How to tell QuickCheck to generate only valid list indices for a parameter?

Say I want to write some unit tests for the (!!) function.
my_prop xs n = ...
I want to restrict n to only valid indexes and I know I could do something like
my_prop xs n = (not.null) (drop n xs) ==> ...
But this makes it so that the vast majority of the generated cases are invalid and get thrown away. Is there a way I can set things up so that QuickCheck generates the xs list first and uses its value to generate only valid cases of n?
Using forAll, you can specify a generator for n which depends on the earlier arguments, e.g.
my_prop (NonEmpty xs) = forAll (choose (0, length xs - 1)) $ \n -> ...
You can make a generator that only creates valid indices and write your property like
import Test.QuickCheck
import Test.QuickCheck.Gen
import System.Random
indices :: [a] -> Gen Int
indices xs = MkGen $ \sg _ -> fst $ randomR (0, length xs - 1) sg
my_prop :: [Char] -> Property
my_prop xs = not (null xs) ==> forAll (indices xs) (\i -> xs !! i /= '0')
eliminating the Int argument.
As suggested by Daniel Wagner, one possibility is creating my own datatype and giving it an Arbitrary instance.
data ListAndIndex a = ListAndIndex [a] Int deriving (Show)
instance Arbitrary a => Arbitrary (ListAndIndex a) where
arbitrary = do
(NonEmpty xs) <- arbitrary
n <- elements [0..(length xs - 1)]
return $ ListAndIndex xs n
NonEmpty is from a custom type in Test.QuickCheck.Modifiers for generating non empty lists.

Boolean selection of list

Suppose we want those elements of list x for which the corresponding element of list y is strictly positive. Any of the three solutions below work:
let x = [1..4]
let y = [1, -1, 2, -2]
[ snd both | both <- zip (map (> 0) y) x, fst both ]
or
map snd $ filter fst $ zip (map (>0) y) x
or
sel :: [Bool] -> [a] -> [a]
sel [] _ = []
sel (True : xs) (y : ys) = y : sel xs ys
sel (False : xs) (y : ys) = sel xs ys
sel (map (> 0) y) x
however, what prompted this was that in the R language this can be written compactly like this:
x[y > 0]
and given how much shorter that is I was wondering if there is a shorter/better way to do this in Haskell?
I'm not a haskell specialist, but why not use list comprehension?
[i | (i,j) <- zip x y, j > 0 ]
If you are willing to use a language extension, I can offer the alternative
{-# LANGUAGE ParallelListComp #-}
bfilter :: (b -> Bool) -> [a] -> [b] -> [a]
bfilter cond xs ys = [x | x <- xs | y <- ys, cond y]
Nothing in Haskell will be nearly as short as the R version, because in R, it's a language built-in, but in Haskell it isn't. Apparently whoever designed R found there to be good reasons to include such a primitive, but none of the Haskell designers found there to be convincing reasons to include such a construct in the language (and it wouldn't fit in nicely, so I fully endorse that decision - it may fit in well in R, I don't know that language).
zip x y >>= \(a,b) -> filter(const(b>0)) [a]
Or pointlessly using Applicative...
import Control.Applicative
zip x y >>= filter <$> const.(>0).snd <*> (:[]).fst
As Daniel Fischer says, there isn't any special syntax for this.
If you're going to be doing this operation often, it's best to define your own single reusable function, instead of having to assemble the list comprehension or map/filter chain manually every time. (Your sel doesn't pass this test because the caller has to apply the map separately.)
So
selectWhere :: [a] -> (a -> Bool) -> [b] -> [b]
selectWhere ys pred = map snd . filter (pred . fst) . zip ys
-- call it like this: selectWhere y (> 0) x
or whichever clearer definition you prefer. The important thing is that you wrap it up inside a function.

Haskell's if statement for error checking

I wrote a function for the Haar wavelet transformation given that the input is a List with a power of 2. I was trying to error check by making sure that the length of the List is a power of 2 before preforming the transformation. I am comparing the log base 2 of the length of the list to see if it comes out evenly (nothing to the right of the decimal point). I think there is something going on with the if statement in haskell that I am not used to in other languages. It works perfectly if I don't error check and just call haar with the proper argument.
haar :: (Fractional a) => [a] -> [a]
haar xs = if logBase 2 (fromIntegral (length xs)) /= truncate (logBase 2 (fromIntegral (length xs)))
then error "The List must be a power of 2"
else haarHelper xs (logBase 2 (fromIntegral (length xs)))
haarHelper xs 1 = haarAvgs xs ++ haarDiffs xs
haarHelper xs level = haarHelper (haarAvgs xs ++ haarDiffs xs) (level - 1)
haarAvgs [] = []
haarAvgs (x:y:xs) = ((x + y) / 2.0) : haarAvgs xs
haarDiffs [] = []
haarDiffs (x:y:xs) = ((x - y) / 2.0) : haarDiffs xs
I am getting the following error message:
functions.hs:52:13:
Ambiguous type variable `t' in the constraints:
`Floating t'
arising from a use of `logBase' at functions.hs:52:13-48
`Integral t'
arising from a use of `truncate' at functions.hs:52:53-99
Probable fix: add a type signature that fixes these type variable(s)
Failed, modules loaded: none.
There's a much simpler and faster implementation to check that a positive integer is a power of two:
import Data.Bits
powerOfTwo' n = n .&. (n-1) == 0
(Note: this omits the check that n is positive, assuming we can rely on it coming from length.)
Explanation, for the curious:
This algorithm relies on the unique property that only powers of 2 have a single 1 bit (by definition), and decrementing them inverts all the lower bits:
2^n = 100000...
2^n - 1 = 011111...
This leaves no bits in common, making their bitwise-and zero.
For all non-powers-of-two, the decrement will leave at least the highest 1 bit unchanged, keeping the bitwise-and result non-zero.
(Wikipedia: Fast algorithm to check if a positive number is a power of two)
haar :: (Fractional a) => [a] -> [a]
haar xs | r /= (truncate r) = error "The List must be a power of 2"
| otherwise = haarHelper xs (logBase 2 (fromIntegral (length xs)))
where r = logBase 2 (fromIntegral (length xs))
Yea, seems like its something with truncate. Easier way to write if then statements with haskell is shown above. Might help with the debugging a bit.
I think i may know. I think truncate is returning an int where the other number is a float.
Try this
haar :: (Fractional a) => [a] -> [a]
haar xs | r /= w = error "The List must be a power of 2"
| otherwise = haarHelper xs (logBase 2 (fromIntegral (length xs)))
where
r = logBase 2 (fromIntegral (length xs))
w = intToFloat (truncate r)
haarHelper xs 1 = haarAvgs xs ++ haarDiffs xs
haarHelper xs level = haarHelper (haarAvgs xs ++ haarDiffs xs) (level - 1)
haarAvgs [] = []
haarAvgs (x:y:xs) = ((x + y) / 2.0) : haarAvgs xs
haarDiffs [] = []
haarDiffs (x:y:xs) = ((x - y) / 2.0) : haarDiffs xs
intToFloat :: Int -> Float
intToFloat n = fromInteger (toInteger n)
To complement Matt's answer:
haar :: (Fractional a) => [a] -> [a]
haar xs | r /= (fromIntegral $ truncate r) = error "The List must be a power of 2"
| otherwise = haarHelper xs r
where r = logBase 2 (fromIntegral (length xs))
Convert the Integral result of truncate using fromIntegral
You can use the definition of r in haarHelper xs r
Here's a version of haar that I'll argue is a little nicer:
haar :: (Fractional a) => [a] -> [a]
haar xs = maybe (error "The List must be a power of 2")
(haarHelper xs)
(intLogBase 2 $ length xs)
intLogBase :: (Integral a) => a -> a -> Maybe Int
intLogBase b n = intLogBase' b 1 n
where
intLogBase' b p 1 = Just p
intLogBase' b p n
| r /= 0 = Nothing
| otherwise = intLogBase' b (p + 1) q
where (q, r) = quotRem n b
intBaseLog is a variation of baseLog that works for integers and returns Nothing if the given number isn't a power of the given base. Otherwise it returns the power wrapped in a Just. Unlike with logBase and truncate there's no conversion to floating point numbers: we've got integers all the way through.
The maybe function in Haar takes three arguments. It will evaluate its last argument, and if it's a Nothing it will return the first argument (in this case the error). If the last argument evaluates to a Just, it applies the second argument to the thing inside the Just and returns that.
The problem here is unrelated to the if expression. As mentioned in other answers, it is in your condition where you compare "logBase (...)" to "truncate (logBase (...))". One returns a Floating type, the other returns an Integral type. There are no types (in the standard libraries) that implement both classes, so that condition can't be well-typed as-is.
A pattern I use occasionally when working with powers of two is to keep a list of powers of two and just check whether the number is in that list. For example:
powersOfTwo :: [Integer]
powersOfTwo = iterate (*2) 1
isPowerOfTwo x = xInt == head (dropWhile (<xInt) powersOfTwo)
where xInt = toInteger x
I haven't tested, but my gut tells me that for most purposes this is probably faster than "logBase 2". Even if not, it's more appropriate because it doesn't involve any floating-point math. In particular, your current approach isn't going to work even with the types fixed: truncate (logBase 2 512) == truncate (logBase 2 550) (Edit: although I think I probably misunderstood your intent when I wrote this at first, i realize now that you probably meant to check whether logBase 2 (...) is an exact integer value by comparing the truncated version to a non-truncated version, not by comparing to any known value).

Resources