Avoiding duplicated QuickCheck properties - haskell

I'm starting to learn Haskell by doing the 99 Haskell problems. http://www.haskell.org/haskellwiki/H-99:_Ninety-Nine_Haskell_Problems I'd like to write tests for each program/function using quickcheck.
I have the following code:
import Test.QuickCheck
import Text.Printf
main = mapM_ (\(s,a) -> printf "%-25s: " s >> a) tests
-- 1
myLast lst = last lst
prop_1a xs x = myLast (xs ++ [x]) == (x::String)
myLast' = head . reverse
prop_1b xs x = myLast' (xs ++ [x]) == (x::String)
tests = [("1a", quickCheck prop_1a)
,("1b", quickCheck prop_1b)
]
I might write myLast'', myLast''', etc. Is there a way I can test all those methods without having to duplicate code and quickcheck properties?
Related question: Right now, I'm telling quickcheck to use Strings. Is there a way to randomly use different types to test against?

Just take the function to test as another argument:
prop_1 last xs x = last (xs ++ [x]) == (x :: Int)
tests = zipWith mkTest ['a'..] [myLast, myLast']
where mkTest letter func = ('1':[letter], quickCheck $ prop_1 func)

Is there a way I can test all those methods without having to duplicate code and quickcheck properties?
Why not write the prop so that it takes a list of functions, and then does the check on each of them? Then you'd run it as quickCheck (myProp [myLast, myLast', myLast'']).
edit: I was afraid you might ask that :P To do it as I said above, myProp should take a list of functions, all of which have the same type as last, and return a boolean:
myProp :: [([a] -> a)] -> Bool
But now that I look at it, it might be better (and more analogous to your original approach) to have it also take a list and an item, so I think I'll do that instead:
myProp :: [([a] -> a)] -> [a] -> a -> Bool
If the list is empty then we return true:
myProp [] _ _ = True
If not, then we check whether the property holds for the first function in the list, then recursively check the rest of the list:
myProp [f:fs] xs x = f (xs ++ [x]) == x && myProp fs xs x
(I'm not sure why you wrote x::String in your implementation. I don't think you should need it -- last works on lists of anything, not just lists of Strings. But I haven't actually tested this out so I assume you had a good reason.)
Anyway, I think that should work but I haven't actually tried it. Please feel free to edit and fix any dumb syntax errors I may have made or whatever.

Related

Create a list of lists for each possible one-change-alteration of a list

I am sorry for not being able to really formulate this question well in the title; I have already asked the same question about triples and have decided to opt for a list after all, so here is the explanation. Thank you for the patience and great help received here!
I need to create a function that is capable of doing the following, yet am quite a newby to Haskell and find myself in need of passing states that is just not in the functional paradigm (nor do I want a semi imperative solution, I just want to know how to do it the functional way). The functionality is as follows:
specialFunc :: [a] -> a -> [[a]]
specialFunc [1,2,3] 0
=> [[0,2,3],[1,0,3],[1,2,0]]
I am trying to create the function by mapping over the list supplied as an argument, but find myself at a loss when I try and figure out how to replace a specific value, add the resulting list to the results and continue working with the next item but with the original list (if that makes sense). Any help is definitely welcome, thank you!
You can define this in a recursive way. If the list is empty (1), then you return an empty list, so [] maps to []. If the list is non-empty (2), then we generate a list where the first item is the tail of the non-empty list, prepended with the value, and we recurse on the tail of the list, and need to prepend the head of the list.
So we can define a function that looks like:
specialFunc :: [a] -> a -> [[a]]
specialFunc xs x = go xs
where go [] = … -- (1)
go (h:hs) = … -- (2)
You can make use of map :: (a -> b) -> [a] -> [b] to prepend the value h to the lists you generate through recursion.
The solution, with many credits to #WillemVanOnsem:
specialFunc :: [a] -> a -> [[a]]
specialFunc xs x = go xs
where go [] = []
go (h:hs) = (x:hs): map (h:) (go hs)
Just to give you another idea of how this could be done, you might turn on the ParallelListComp extension and zip up the result of inits and tails appropriately:
{-# Language ParallelListComp #-}
import Data.List
specialFunc xs x = [pre ++ [x] ++ suf | pre <- inits xs | _:suf <- tails xs]
The same idea can also be done without an extension, of course, though I think it's not quite as pretty:
import Data.List
specialFunc xs x = zipWith (\pre suf -> pre ++ [x] ++ suf) (inits xs) (tail (tails xs))

Haskell's span function

I'm relatively new to Haskell and I'm struggling to figure out a way to implement Haskell's span function. However, my problem is more general than that in that I don't know how to make a function return a list of lists or list of tuples containing the elements I want. My problem with a list of lists such as:
[[1],[2]]
is that I can't make the function add an element to the first list in the list of lists. I only know how to append another list to the list of lists.
In short, if you explain to me how to implement the span function, this all should hopefully come clear to me.
So I think what you're saying is that you know how to recursively append to a list by doing something like
foobar :: [x] -> [y]
foobar ( []) = []
foobar (x:xs) = {- ...stuff... -} : foobar xs
but you have no idea how to do that with two lists:
foobar :: [x] -> ([y], [z])
foobar (x:xs) = ???
In general, when the result isn't a list, but something that contains a list, you end up doing something like this:
foobar :: [x] -> ([y], [z])
foobar (x:xs) =
let
y = {- whatever -}
z = {- whatever -}
(ys, zs) = foobar xs -- The recursive call
in (y:ys, z:zs)
The same applies if, say, the result is a monadic action
foobar :: [x] -> IO [y]
foobar (x:xs) = do
y <- {- whatever -}
ys <- foobar xs
return (y:ys)
Note that this forces the function to not be lazy.
The general pattern I think you'll want to use here is the following:
span :: (a -> Bool) -> [a] -> ([a], [a])
span pred [] = ([], [])
span pred (x:xs) = if pred x then _ else _ -- fill in the blanks
where (prefix', suffix') = span pred xs
There are two non-obvious things there. First, note the pattern match in the where condition. This means that we're:
Calling span pred xs, which produces a pair of lists;
Pattern matching on this pair;
Naming the first and second element of the pair prefix' and suffix' respectively.
I suspect that step #2, the pattern match on the result of the recursive call, is something you might not have understood.
The second non-obvious thing is recursion. It's a tricky thing because, counterintutively, to solve a problem with recursion you need to assume that you've already solved it, but for the "wrong" argument--a tough step to picture yourself taking if you haven't solved it yet! But the trick is this:
Imagine you've actually already solved the problem, but for the tail of the list. That's what the prefix' and suffix' variables contain: a correct solution but for the wrong list--the tail of the one you're actually trying to solve for.
Given that (non)solution, how could you reuse it to arrive at a correct solution for your problem?

How to expect exceptions with QuickCheck2

I've been trying to pick up Haskell recently, but I am having some difficulty with QuickCheck2 (which I'm trying to learn while coding up the 99 problems). I've looked at this question along with related ones on the matter.
Like OP from the aforementioned question, I'm interested in finding out whether it is possible for QuickCheck2 to expect exceptions. I know this is possible with QuickCheck 1. Some googling around led me to the following version of my code to test a myLast function which returns the last element of a list:
prop_myLast :: [Int] -> Bool
prop_myLast [] = expectFailure . myLast $ []
prop_myLast xs = myLast xs == last xs
Of course, this (1) does not typecheck, since expectFailure returns a Property and (2) requires an import from v1 of QuickCheck. Regarding (1) I don't really see how to make this work - I tried looking up how to catch exceptions on my own but was met with more difficulty because this started bringing in the IO monad. With respect to (2) I don't know if bringing in the expectFailure function is a good idea in the first place - could anyone experienced with the system tell me if I'm supposed to be using components from both v1 and v2? If not, where is the analogous expectFailure for v2 of QuickCheck?
You use expectFailure like this:
prop :: Int -> Bool
prop x = x + 1 == x -- should always be False
main = quickCheck (expectFailure prop)
However, expectFailure only tests that there is at least one test case which fails - i.e. it really expects your code to fail. You want QuickCheck to ignore any failures in the event that it passes the empty list to prop_myLast.
One way to do this is with the ==> operator:
prop_myLast :: [Int] -> Property
prop_myLast xs = not (null xs) ==> myLast xs == last xs
Another example:
prop_cubed :: Int -> Property
prop_cubed x = (x > 1) ==> x^3 > x -- note: not true for negative values so don't
-- test those cases
Quickcheck will discard generated test cases which do not match the conditional.
Update: One way of explicitly testing the [] case is:
quickCheck $ expectFailure $ seq (myLast []) True
The expression seq a True will return True unless a throws an exception or diverges.

Detect bottom value in Haskell

I've written a haskell function which splits a list xs into (init xs, last xs) like so:
split xs = split' [] xs
where
split' acc (x:[]) = (reverse acc, x)
split' acc (x:xs) = split' (x:acc) xs
Since an empty list can not be split in this way, there is no match for the empty list. However, I did not want to simply error ... the function. Thus I defined the following:
split [] = ([], undefined)
Thanks to lazy evaluation I can thus define a safe init which simply returns the empty list for the empty list:
init' = fst . split
Is there some way how I could detect the undefined if I tried to access it, such that
last' xs
| isUndefined (snd xs) = ...
| otherwise = ...
I do know about Maybe and Either, and that those are a better choice for expressing what I want. However I wondered if there is a way to detect an actual value of undefined, i.e. in terms of catching errors, like catching exceptions.
undefined is no better than using error. In fact, undefined in Prelude is defined as
undefined = error "Prelude.undefined"
Now, a function that can't result in an error is called a "total function", i.e. it is valid for all input values.
The split function you've currently implemented has the signature
split :: [a] -> ([a], a)
This is a problem, since the type signature promises that the result always contains a list and an element, which is clearly impossible to provide for empty lists of generic type.
The canonical way in Haskell to address this is to change the type signature to signify that sometimes we don't have a valid value for the second item.
split :: [a] -> ([a], Maybe a)
Now you can write a proper implementation for the case where you get an empty list
split [] = ([], Nothing)
split xs = split' [] xs
where
split' acc (x:[]) = (reverse acc, Just x)
split' acc (x:xs) = split' (x:acc) xs
Now you can detect the missing value case by pattern-matching
let (init', last') = split xs
in case last' of
Nothing -> ... -- do something if we don't have a value
Just x -> ... -- do something with value x
Because bottom subsumes non-termination, the function isUndefined would have to solve the halting problem and thus cannot exist.
But note that even if it existed, you still could not tell if the undefined value in the 2nd element of your tuple was put there through your split function or if the last element of the list was already undefined.
The error function doesn't do anything until it is evaluated, so you can do something like:
split [] = ([], error "split: empty list")
last' = snd . split
From the Haskell 2010 Language Report > Introduction # Values and Types
Errors in Haskell are semantically equivalent to ⊥ (“bottom”). Technically, they are indistinguishable from nontermination, so the language includes no mechanism for detecting or acting upon errors.
To be clear, undefined is intended to be a way to insert ⊥ into your program, and given that (as shang noted) undefined is defined in terms of error, there is, therefore, "no mechanism for detecting or acting upon undefined".
Although semantically speaking Ingo's answer is correct, if you're using GHC, there is a way using a couple of "unsafe" functions that, although not quite perfect as if you pass it a computation of type IO a which contains an exception it will return True, works. It's a bit of a cheat though :).
import Control.Exception
import System.IO.Unsafe
import Unsafe.Coerce
isUndefined :: a -> Bool
isUndefined x = unsafePerformIO $ catch ((unsafeCoerce x :: IO ()) >> return False) (const $ return True :: SomeException -> IO Bool)
I know this is horrible, but none the less it works. It won't detect non termination though ;)

Fastest way to get the last element of a list in Haskell

What is the fastest way to get the last element of a list in Haskell. Also in next iteration, I want to remove first and last element of the list. What is the most elegant way to do it? I am trying list comprehension, but that does not look very efficient!
You can use the last function to get the last element of a list.
As for how to remove the first and last elements, you could use (init . tail), but I don't know how efficient that is.
I think this image from Learn You A Haskell shows the list functions fairly well:
last and init will do the job just fine for a one-off. However they are both O(n), so if you need to manipulate both ends of a list often, as you seem to imply, you might want to consider using Data.Sequence instead, which supports O(1) insertion and removal of items at both ends.
I'll post the Prelude implementation since it hasn't been posted yet:
listLast :: [a] -> a
listLast [x] = x --base case is when there's just one element remaining
listLast (_:xs) = listLast xs --if there's anything in the head, continue until there's one element left
listLast [] = error "Can't do last of an empty list!"
Note that I changed the function name to listLast so that it can be run without conflicting with normal Prelude. You could, of course, do import Prelude hiding(last).
To remove first and last:
take (len(l)-2) (drop 1 l)
or maybe
init (drop 1 l)
This also results in almost optimal code.
This answer focuses on dealing with weird conditions (like empty lists) in a maximally flexible way, and on building up bigger functions from smaller ones using some library functions. It's not the best answer for someone first learning about lists, but rather a couple steps past that.
For the following, you will need
import Control.Monad ((>=>))
and you will need to either use GHC 7.10 and import Data.List (uncons) or define
uncons :: [a] -> Maybe (a, [a])
uncons [] = Nothing
uncons (x:xs) = Just (x,xs)
You can write a safe form of init like this:
init' :: [x] -> Maybe [x]
init' = foldr go Nothing
where
go x mxs = Just (maybe [] (x:) mxs)
A version of tail can be written
tail' :: [a] -> Maybe [a]
tail' = fmap snd . uncons
So then you can get a maybefied
trim' :: [a] -> Maybe [a]
trim' = init' >=> tail'
The >=> is a sort of backwards monadic composition. init' >=> tail' is a function that applies init' to its argument to get a Maybe [a]. If it gets Nothing, it returns that. If it gets Just xs, it applies tail' to xs and returns that.
From this, you can easily make a trimmer that trims lists with 0, 1, or 2 elements down to empty lists:
trim :: [a] -> [a]
trim = maybe [] id . trim'
last' :: [a] -> a
last' ys = foldl1 (\_ -> \x -> x) ys
It is O(n), just like the built in library function list.
(head.reverse) [1..100]
Is an alternative to last to get the last element.
drop 1 (take (length [1..100] - 1) [1..100])
removes the first and last list element. The source for drop and take look like it might be faster than (init . tail).
(reverse.drop 1) ((reverse.drop 1) [1..100])
is another variant. But I guess slower because of the double reversal.

Resources