Generate new test data inside QuickCheck property - haskell

I'm having trouble with a programming problem here. Half the trouble is that the problem itself is quite tricky to think about, and the other half is that I can't remember how to find my way around QuickCheck.
I know that if you write a function that takes several arguments that have an Arbitrary instance, QuickCheck will let you use that method as a test. What I can't figure out is how to generate new test arguments inside that method. I want to write something like
prop13 :: Foo -> Bar -> Bool
prop13 foo bar =
if foobar foo bar
then fn1 foo
else newInput $ \ baz -> fn2 foo bar baz
but I can't figure out how the hell to do that.
Actually, no, what I really want to write is
prop13 :: Foo -> Bar -> Property
prop13 foo bar =
if foobar foo bar
then label "foobar=YES" $ fn1 foo
else label "foobar=NO" $ newInput $ \ baz -> fn2 foo bar baz
just so I can check it isn't taking one branch 100% of the time or something ridiculous like that.
Actually, what would be great is if I could demand that baz has some particular property. I vaguely remember QuickCheck having a function somewhere to throw away inputs not satisfying a given condition. (The only problem being that it might take an unreasonably number of attempts to satisfy the condition...)
Is there a way to do this? I'm staring at the Haddock page, but I can't figure out how to get what I want...

A property may take the form
classify <condition> <string>$ <property>
For example,
prop_Insert x xs =
ordered xs ==>
classify (ordered (x:xs)) "at-head" $
classify (ordered (xs ++ [x])) "at-tail" $
ordered (insert x xs)
where types = x :: Int
Test cases satisfying the condition are assigned the classification
given, and the distribution of classifications is reported after
testing. In this case the result is
Main> quickCheck prop_Insert
OK, passed 100 tests. 58% at-head,
at-tail. 22% at-tail. 4% at-head.
Note that a test case may fall into more than one classification.
(from QuickCheck manual)
For demanding the particular property of the input data, you may add somePredicate data ==> before the test body, as it is shown in the snippet above. Another example:
prop_max xs = (not . null xs) ==> head (sort xs) == maximum xs
You're right, this combinator throws away inappropriate cases. If that's undesired, you can make a newtype wrapper over the input type and redefine the Arbitrary instance for it (see examples of Positive, NonEmpty and so on here)

I found the answer in another answer. Apparently it's forAll:
else forAll arbitrary $ \ baz -> fn2 foo bar baz
I just couldn't remember how to do it...
(This also has the nice feature of allowing me to specify a specific random data generator.)

Related

Pass more than 1 parameter to monad

I'm learning Haskell and making up some examples. I'm not sure why the second example doesn't work
foo :: Int -> Int -> Maybe Int
foo 0 0 = Nothing
foo a b = Just $ a + b
bar :: Int -> Maybe Int
bar 0 = Nothing
bar a = Just $ a + 1
-- This works
Just 4 >>= bar
-- Why this doesn't work?
(Just 4 Just 4) >>= foo
-- This works
do
a <- Just 3
b <- Just 4
foo a b
As the comment says, (Just 4 Just 4) tries to apply the constructor Just to 3 arguments when it only takes one. So, I will assume that you wanted something like (Just 4, Just 4), and want it to work like your final example.
The type of the "bind" operator is (>>=) :: Monad m => m a -> (m a -> b) -> m b. This means that the function expected after the operator only takes one argument, not two. So, again, the ultimate reason why it doesn't work is that, your function takes the wrong number of arguments. (Partial application means that you don't have to provide all the arguments at once, but it sounds like you're expecting some other piece of data to be magically routed to the missing argument...)
Desugaring your do example to >>= form translates as:
Just 3 >>= \a -> Just 4 >>= \b -> foo a b
To make this a little clearer, I'll parenthesize the lambdas:
Just 3 >>= ( \a -> Just 4 >>= (\b -> foo a b) )
That makes it easier to see that you can simplify the inner lambda:
Just 3 >>= ( \a -> Just 4 >>= foo a )
So, it's possible after all to route the missing data to the extra argument! But, you do have to work out the routing yourself...
There's nothing particularly magical about Haskell functions; they tend to be more particular about how they're called than dynamic languages. The largest "magic" here is that the type checker can often tell when you're not using them correctly.
And (as the other answer notes) there is nothing magical about >>= -- it's just another function, and in order to understand how to use it, you need to take a look at its type.
It doesn't work because >>= is a perfectly normal operator (and operators are perfectly normal functions).
You seem to be thinking of >>= as special syntax for getting values out of the monadic value on its left and feeding it to the function on the right. It is not special syntax; rather >>= itself is a function that gets applied to the values on its left and its right (and then computes a result as you expect).
However, that means that the left and right arguments must be valid expressions for things that could exist as ordinary values; things you could simply bind to variables with var = <expr> syntax. Just 4 >>= bar works because (among other requirements) Just 4 on its own is a valid expression of type Maybe Int and bar is a valid expression of type Int -> Maybe Int. Just 4 Just 4 >>= foo doesn't work because Just 4 Just 4 is not a correct expression (what would it's type be?); it's interpreted as applying Just to the 3 separate arguments 4, Just, and 4, whereas you want it to be two separate values Just 4 and Just 4. But even if you could get the compiler to interpret something there as two separate values, there's no way for >>= to be passed two separate values as its left argument; it's expecting (in this usage) a single value of type Just Int.
If you have a function like foo that needs two arguments and you want to source those arguments from values that are in a monadic context, then you can't just apply >>= you need to write code that does that (like your final example with the do block; there are many other ways to do something equivalent).
The other answers described why this doesn't work. But IMO it's quite reasonable that you want this, and indeed Just 3 >>= \x -> Just 4 >>= \y -> foo x y is a bit of a silly solution to the task. Basically, the x and y values are independent of each other, yet you're fetching them sequentially, in a way that the complete y calculation could in principle depend on the value of x.
Monads aren't really the right abstraction here, they're too strong. To get x and y non-sequentially, you can use Applicative interface. The form that most Haskellers prefer nowadays (I think) is
foo <$> Just 3 <*> Just 4
You can read this as “zip the effectful values Just 3 and Just 4 together to a single action with two values, then apply foo over those values”.
...Actually that's not really how it works though, and for me that was super confusing when I first learned about applicatives. Namely, the above expression is in fact parsed as
(foo <$> Just 3) <*> Just 4
which looks again like it's sequential-style. But it's not, what going on here is only a currying/laziness trick to pass multiple values through the applicative value without having to group them to a suitable tuple. The code that literally works like I explained it would be
uncurry foo <$> ((,)<$>Just 3<*>Just 4)
Here, (,)<$>Just 3<*>Just 4 evaluates to Just (3,4). Then fmapping foo over that needs to be done in uncurried form, so the two arguments are accepted as a tuple. It's structurally clear, yet awkward because we're working against Haskell's curried style.
(Mathematically, this tupling is what's conceptually happing though: generally speaking, you're working in a monoidal category. Some other incarnations of applicative functors have such a tuppling-combinator as their underlying interface, instead of <*>; e.g. >*< from the invertible package.)
The trick with foo<$>Just 3<*>Just 4 is that instead of building a tuple, we start with partially applying foo to the 3 result. This doesn't actually require anything applicative/monadic yet – we're basically just transforming the contained value – in general: values – from 3 to foo 3, without touching their context. You may consider this a purely symbolic operation. Note that the type is Maybe (Int -> Int) at this point.
Then you use the <*> combinator to zip both of the Maybe contexts together, and simultaneously apply the foo 3 partially-evaluated function to its second argument.
I personally like this form, which is also equivalent:
liftA2 foo (Just 3) (Just 4)
We're not finished yet though: all the above suggestions give a result of type Maybe (Maybe Int). To flatten that into a Maybe Int, that's where you actually need the monad interface. One option is
join $ foo <$> Just 3 <*> Just 4

Apply function to argument before performing pattern matching

I'm new to Haskell and trying to not instinctively think imperatively. I have a function which does all the work in a pattern matching block, however it needs to pattern match on the argument after a function is applied to it.
Doing this in a functional way gets me to this:
foo :: Int -> String
foo n = bar $ show n
bar :: String -> String
bar [] = ""
bar (c:s) = "-" ++ bar s
Where foo is the function I'm trying to implement but bar is where all the work gets done. foo only exists to provide the right type signature and perform the precursor show transformation before calling bar. In practice, bar could get quite complicated, but still, I have no reason to expose it as a separate function.
What's the Haskell way to perform a simple function like show and "then" pattern match on the result of that?
I tried changing the pattern matching to a case statement, but it didn't permit the all-important recursion, because there was no function to call recursively. For the same reason, using a where clause applied to multiple patterns also doesn't work.
I remembered that Learn You A Haskell often seemed to emphasise that where and let are more powerful than they first seem because "everything is a function" and the clauses are expressions themselves.
That prompted me to see if I could push where a bit harder and use it to essentially define the helper function bar. Turns out I can:
foo :: Int -> String
foo n = bar $ show n
where bar [] = ""
bar (c:s) = "-" ++ bar s
Unless there's a better way, I think this is the solution I'm after. It took a bit of beating back my imperative tendencies to see this, but it's starting to look logical and much more "core" than I was imagining.
Please provide an alternative answer if these assumptions are leading me off course!
It depends on whether the pattern-matching function is recursive or not.
In your example, it is called bar and is recursive.
foo :: Int -> String
foo n = bar $ show n
bar :: String -> String
bar [] = ""
bar (c:s) = "-" ++ bar s
Here, the (arguably) best solution is the one you found: use where (or let) and define it locally to foo:
foo :: Int -> String
foo n = bar $ show n
where
bar :: String -> String -- optional type annotation
bar [] = ""
bar (c:s) = "-" ++ bar s
The type annotation for the inner function is optional. Many Haskellers think that the top-level function foo should have its signature (and GHC with -Wall warns if you do not provide it) but also believe that the inner function do not have to be annotated. For what it is worth, I like to add it when I think it's non obvious from the context. Feel free to include or omit it.
When bar is not recursive, we have other options. Consider this code:
foo :: Int -> String
foo n = bar $ show n
bar :: String -> String
bar [] = "empty"
bar (c:s) = "nonempty " ++ c : s
Here, we can use case of:
foo :: Int -> String
foo n = case show n of
[] -> "empty"
(c:s) -> "nonempty " ++ c : s
This calls function show first, and then pattern-matches its result. I think this is easier to read than adding a where to define bar.
Theoretically, speaking, we could follow the case approach even in the recursive case, and leverage fix (a function from the library) to close the recursion. I do not recommend you to do this, since defining bar using where (or let) is more readable. I'm adding this less readable option here only for the sake of completeness.
foo :: Int -> String
foo n = fix (\bar x -> case x of
[] -> ""
(c:s) -> "-" ++ bar s
) $ show n
This is equivalent to the first recursive code snippet, but it requires much more time to read. The helper fix has its uses, but if I read this in actual production code I'd think the programmer is trying to show they are "clever" instead of writing simple, readable code.

Maybe-like monad that gives breadcrumbs when Nothing occurs

I have two record types
data OptionalRecord = OptionalRecord
{ mFoo :: Maybe Foo
, mBar :: Maybe Bar
, mBaz :: Maybe Baz
}
data RequiredRecord = RequiredRecord
{ foo :: Foo
, bar :: Bar
, baz :: Baz
}
I have a function:
optionalToRequired :: OptionalRecord -> Maybe RequiredRecord
optionalToRequired OptionalRecord{..} =
do
foo <- mFoo
bar <- mBar
baz <- mBaz
return RequiredRecord{..}
This funcion works fine, but when it returns Nothing, I don't have any info about which field (or line in the do block) was Nothing.
Does anyone have any suggestions for an alternative that includes more info, like line number, that doesn't require a lot of embellishment?
William's suggestion in the comments is a good one: if you use Either instead of Maybe, then instead of Nothing, your computations can produce information about why they failed. But you do have to provide this information: you can't just get it automatically from the compiler with a line number for the bind. Indeed you can't introduce any information with a bind that doesn't come from the monadic value being binded, because this would break the Monad laws.
A common example of this is "What if I could count how many calls to >>= (or uses of <- in do-notation) there have been?". You can see why that doesn't work in the question Is it possible to create a Monad that count the number of instructions?.
As others have stated, Either a meets the requirements you've mentioned, but there is a very good reason for this: Either a behaves the same as Maybe as a Monad.
It can only hold a single value or no values.
An "error" value (Left foo or Nothing) short-circuits further computations whereas a "success" value (Right bar or Just bar) does not. (This means that you can only use Right as an indication of success and Left as an indication of an error.)
You can pattern-match "error" and "success" values at the end.
There is a large variety of Monad semantics out there, and having the concept of an error message isn't alone sufficient to take the place of Maybe.

"For all" statements in Haskell

I'm building comfort going through some Haskell toy problems and I've written the following speck of code
multipOf :: [a] -> (Int, a)
multipOf x = (length x, head x)
gmcompress x = (map multipOf).group $ x
which successfully preforms the following operation
gmcompress [1,1,1,1,2,2,2,3] = [(4,1),(3,2),(1,3)]
Now I want this function to instead of telling me that an element of the set had multiplicity 1, to just leave it alone. So to give the result [(4,1),(3,2),3] instead. It be great if there were a way to say (either during or after turning the list into one of pairs) for all elements of multiplicity 1, leave as just an element; else, pair. My initial, naive, thought was to do the following.
multipOf :: [a] -> (Int, a)
multipOf x = if length x = 1 then head x else (length x, head x)
gmcompress x = (map multipOf).group $ x
BUT this doesn't work. I think because the then and else clauses have different types, and unfortunately you can't piece-wise define the (co)domain of your functions. How might I go about getting past this issue?
BUT this doesn't work. I think because the then and else clauses have different types, and unfortunately you can't piece-wise define the (co)domain of your functions. How might I go about getting past this issue?
Your diagnosis is right; the then and else must have the same type. There's no "getting past this issue," strictly speaking. Whatever solution you adopt has to use same type in both branches of the conditional. One way would be to design a custom data type that encodes the possibilities that you want, and use that instead. Something like this would work:
-- | A 'Run' of #a# is either 'One' #a# or 'Many' of them (with the number
-- as an argument to the 'Many' constructor).
data Run a = One a | Many Int a
But to tell you the truth, I don't think this would really gain you anything. I'd stick to the (Int, a) encoding rather than going to this Run type.

Haskell - assert a function was called

Is it possible to verify that a function was called in Haskell HSpec?
Assuming I had two functions foo and bar that transform my data.
foo :: Stuff -> Stuff
bar :: Stuff -> Stuff
And I have a function that applies either foo or bar on Stuff depending on whether it received 'f' or 'b' as its second argument and returns the result of the applied function.
apply :: Stuff -> Char -> Stuff
And In my tests, I have tested each of the functions foo and bar comprehensively that i would not want to test there effect with in apply.
Is it possible for me to verify that a function foo or bar was called? depending on what argument is passed to apply?
"I'm thinking more TDD, like in an OOP language. Is such a thing possible in Haskell?"
A better question is "is such a thing necessary in Haskell?" ;-)
[I realise that is not the question you actually asked. Feel free to ignore this answer.]
In an OO language, we build objects that talk to other objects to get their job done. To test such an object, we build a bunch of fake objects, hook the real object up to the fake ones, run the method(s) we want to test, and assert that it calls faked methods with the expected inputs, etc.
In Haskell, we write functions. The only thing a pure function does is take some input, and produce some output. So the way to test that is to just run the thing, feeding it known inputs and checking that it returns known outputs. What other functions it calls in the process of doing that doesn't matter; all we care about is whether the answer is right.
In particular, the reason we don't usually do this in OOP is that calling some arbitrary method might cause "real work" to happen — reading or writing disk files, opening network connections, talking to databases and other servers, etc. If you're just testing one part of your code, you don't want the test to depend on whether some database is running on a real network server somewhere; you just want to test one little part of your code.
With Haskell, we separate anything that can affect the Real World from stuff that just does data transformations. Testing stuff that just transforms data in memory is delightfully trivial! (Testing the parts of your code that do interact with the Real World is still hard, in general. But hopefully those parts are very small now.)
The Haskell test style of choice seems to be property-based testing. For example, if you've got a function to solve an equation, you write a QuickCheck property that randomly generates 100 equations, and for each one, it checks whether the number returned actually solves the original equation or not. It's a tiny handful of code that automatically tests just about everything you'd ever want to know! (But not quite: You need to make sure that the "randomly" chosen equations actually test all the code paths you care about.)
(No exactly Haskell, but close.)
fooP = point . foo
-- testable property: forall s. foo s = runIdenity $ fooP s
barP = point . bar
-- similar testable property
fooAndWitness :: Stuff -> Writer String Stuff
fooAndWitness = fooM >> tell "foo"
-- testable property forall s. (foo s, "foo") = runWriter $ fooAndWitness s
barAndWitness :: Stuff -> Writer String Stuff
barAndWitness = barM >> tell "bar"
-- similar testable property
applyOpen :: Pointed p => (Stuff -> p Stuff) -> (Stuff -> p Stuff) -> Stuff -> Char -> p Stuff
applyOpen onF _ x 'f' = onF x
applyOpen _ onB x 'b' = onB x
applyOpen _ _ x _ = point x
-- semi-testable property (must fix p):
-- forall f b s c. let a = applyOn f b s c in a `elem` [f s, b s, point s]
-- In particular, if we choose p carefully we can be, at least stochastically,
-- sure that either f, b, or neither were called by having p = Const [Int], and running several tests
-- where two random numbers are chosen, `f _ = Const $ [rand1]`, and `b _ = Const $ [rand2]`
-- and verifying we get one of those numbers, which could not have been known when applyOpen was written.
applyM = applyOpen fooM barM
-- similar testable property, although but be loose the "rigged" tests for variable f/b, so
-- some of our correctness may have to follow from the definition.
apply = (runIdentity .) . applyM
-- similar testable property and caveat
Pointed is a type class that fits between Functor and Applicative and provides point with the same semantics as pure or return. It's only law follows from parametricity: (. point) . fmap = (point .)

Resources