let list p = if List.contains " " p || List.contains null p then false else true
I have such a function to check if the list is well formatted or not. The list shouldn't have an empty string and nulls. I don't get what I am missing since Check.Verbose list
returns falsifiable output.
How should I approach the problem?
I think you don't quite understand FsCheck yet. When you do
Check.Verbose someFunction
, FsCheck generates a bunch of random input for your function, and fails if the function ever returns false. The idea is that the function you pass toCheck.Verbose
should be a property that will always be true no matter what the input is. For example, if you reverse a list twice then it should return the original list no matter what the original list was. This property is usually expressed as follows:Your function, on the other hand, is a good, useful function that checks whether a list is well-formed in your data model... but it's not a property in the sense that FsCheck uses the term (that is, a function that should always return true no matter what the input is). To make an FsCheck-style property, you want to write a function that looks generally like:
(Note that I've named your function
myFunc
instead oflist
, because as a general rule, you should never name a functionlist
. The namelist
is a data type (e.g.,string list
orint list
), and if you name a functionlist
, you'll just confuse yourself later on when the same name has two different meanings.)Now, the problem here is: how do you write the "input is well-formed" part of my
verifyMyFunc
example? You can't just use your function to check it, because that would be testing your function against itself, which is not a useful test. (The test would essentially become "myFunc input = myFunc input", which would always return true even if your function had a bug in it — unless your function returned random input, of course). So you'd have to write another function to check if the input is well-formed, and here the problem is that the function you've written is the best, most correct way to check for well-formed input. If you wrote another function to check, it would boil down tonot (List.contains "" || List.contains null)
in the end, and again, you'd be essentially checking your function against itself.In this specific case, I don't think FsCheck is the right tool for the job, because your function is so simple. Is this a homework assignment, where your instructor is requiring you to use FsCheck? Or are you trying to learn FsCheck on your own, and using this exercise to teach yourself FsCheck? If it's the former, then I'd suggest pointing your instructor to this question and see what he says about my answer. If it's the latter, then I'd suggest finding some slightly more complicated function to use to learn FsCheck. A useful function here would be one where you can find some property that should always be true, like in the
List.rev
example (reversing a list twice should restore the original list, so that's a useful property to test with). Or if you're having trouble finding an always-true property, at least find a function that you can implement in at least two different ways, so that you can use FsCheck to check that both implementations return the same result for any given input.