How can QuickCheck test all properties for each sample - haskell

...instead of generating 100 new random samples for each property?
My testsuite contains the TemplateHaskell hack explained here [1] to
test all functions named prop_*. Running the test program prints
=== prop_foo from tests/lala.lhs:20 ===
+++ OK, passed 100 tests.
=== prop_bar from tests/lala.lhs:28 ===
+++ OK, passed 100 tests.
and it looks like going through 100 random samples for each of the
properties.
Problemis: Generating the samples is quite expensive, checking the
properties is not. So I'd like to have a means to pass each random
sample to each of the prop_* functions instead of creating new
(#properties * 100) many samples.
Is there anything like that built in? Actually, I think I'd need a
replacement for the splice
$(forAllProperties)
in
main :: IO ()
main
= do args <- parseArgs <$> getArgs
s <- $(forAllProperties) $ quickCheckWithResult args
s ? return () $ exitFailure
where
parseArgs as
= null as ? stdArgs $ stdArgs{ maxSuccess = read $ head as }
[1] Simple haskell unit testing, and
QuickCheck exit status on failures, and cabal integration

In this post you can see how to group tests
Stackoverflow post
That user provides a very simple example of use Test.Tasty.QuickCheck
Using testProperty and testGroup you can pass each random sample to each property
In the next link you can check the hackage of this package
Test.Tasty.QuickCheck

Related

Haskell: initialise a list with symbols?

In Haskell, is there a way of initialising a list and declaring symbols in that list at the same time?
Currently I do this:
import Data.List
main = do
let lambda = "\x03BB"
xi = "\x926"
bol = "\x1D539"
cohomology_algebra = [ lambda, bol, xi]
putStrLn $ xi
putStrLn $ show cohomology_algebra
However I have a long list of symbols and I worry that i forget to put them all in the list (it has happened)
Ideally I would do something like:
main = do
let cohomology_algebra = [ lambda = "\x03BB", bol = "\x1D539", xi= "\x926"] -- does not compile
putStrLn $ show cohomology_algebra
Is there a way around this?
Not a perfect solution, but you could use
let cohomology_algebra#[lambda, bol, xi] = ["\x03BB", "\x926", "\x1D539"]
This will trigger a runtime error if the two lists above have different length (at the point where the names are demanded).
It's not optimal, since this check should be at compile time instead. Further, in this code style we have to separate the identifier form its value too much, making it possible to swap some definitions by mistake.

How to show progress in Shake?

I am trying to figure out how can i take the progress info from a Progress type (in Development.Shake.Progress) to output it before executing a command. The possible desired output would be:
[1/9] Compiling src/Window/Window.cpp
[2/9] Compiling src/Window/GlfwError.cpp
[3/9] Compiling src/Window/GlfwContext.cpp
[4/9] Compiling src/Util/MemTrack.cpp
...
For now i am simulating this using some IORef that keeps the total (initially set to the sum of the source files) and a count that i increase before executing each build command, but this seems like a hackish solution to me.
On top of that this solution seems to work correctly on clean builds, but misbehaves on partial builds as the sum that displayed is still the total of all the source files.
With access to a Progress data type i will be able to calculate this fraction correctly using its countSkipped, countBuild, and countTodo members (see Progress.hs:53), but i am still not sure how i can i achieve this.
Any help is appreciated.
Values of type Progress are currently only available as an argument to the function stored in shakeProgress. You can obtain the Progress whenever you want with:
{-# LANGUAGE RecordWildCards #-}
import Development.Shake
import Data.IORef
import Data.Monoid
import Control.Monad
main = do
ref <- newIORef $ return mempty
shakeArgs shakeOptions{shakeProgress = writeIORef ref} $ do
want ["test" ++ show i | i <- [1..5]]
"test*" %> \out -> do
Progress{..} <- liftIO $ join $ readIORef ref
putNormal $
"[" ++ show (countBuilt + countSkipped + 1) ++
"/" ++ show (countBuilt + countSkipped + countTodo) ++
"] " ++ out
writeFile' out ""
Here we create an IORef to squirrel away the argument passed to shakeProgress, then retrieve it later when running the rules. Running the above code I see:
[1/5] test5
[2/5] test4
[3/5] test3
[4/5] test2
[5/5] test1
Running at a higher level of parallelism gives less precise results - initially there are only 3 items in todo (Shake increments countTodo as it finds items todo, and spawns items as soon as it knows about any of them), and there are often two rules running at the same index (there is no information about how many are in progress). Given knowledge of your specific rules, you could refine the output, e.g. storing an IORef you increment to ensure the index was monotonic.
The reason this code is somewhat convoluted is that the Progress information was intended to be used for asynchronous progress messages, although your approach seems perfectly valid. It may be worth introducing a getProgress :: Action Progress function for synchronous progress messages.

unreadable quickcheck log file after a test routine

I made a test routine for a Haskell program with quickcheck. I declared it in my cabal file with :
Test-Suite routine_de_test
Type: exitcode-stdio-1.0
Hs-Source-Dirs: test
Main-is: Tests.hs
and launched it with :
cabal configure --enable-tests
cabal buil
cabal test
The tests are processed correctly and I was expecting to see details about the random value used for each test in the log file dist/test/ but when I open it, the file looks like this :
I tried to open the file with several encoding (UTF8, ISO-8859-15, ...) but nothing is changed.
Is it normal? Or is there something wrong?
Is it possible when performing quickcheck test from cabal to get the complete list of random values used for each tests?
It looks like the funny characters are simply backspaces, and quickcheck is simply reporting the number of tests it has performed so far by overwriting (0 tests) with (1 test) and then (2 tests) and then with (3 tests), etc.
Visually it will look fine when displayed to a terminal.
Update:
To report the random values used for a test the only way I know of is to write your test to explicitly display (or save to a file) the values used.
If your test is a pure function you can use the trace function from Debug.Trace. For instance, if you have this property:
prop_commutes :: Int -> Int -> Bool
prop_commutes a b = a + b == b + a
You can trace each invocation of prop_commutes by modifying like this:
import Debug.Trace
prop_commutes :: Int -> Int -> Bool
prop_commutes x y = a + b == b + a
where (a,b) = trace ("(a,b) = " ++ show (x,y)) (x,y)
and then quickCheck prop_commutes will emit lines like:
(x,y) = (20,-73)
(x,y) = (71,-36)
(x,y) = (2,-11)
...
in addition to its normal output.

can xmonad's logHook be run at set intervals rather than in (merely) response to layout events?

I'm using dynamicLogWithPP from XMonad.Hooks.DynamicLog together with dzen2 as a status bar under xmonad. One of the things I'd like to have displayed in the bar is the time remaining in the currently playing track in audacious (if any). Getting this information is easy:
audStatus :: Player -> X (Maybe String)
audStatus p = do
info <- liftIO $ tryS $ withPlayer p $ do
ispaused <- paused
md <- getMetadataString
timeleftmillis <- (-) <$> (getCurrentTrack >>= songFrames) <*> time
let artist = md ! "artist"
title = md ! "title"
timeleft = timeleftmillis `quot` 1000
(minutes, seconds) = timeleft `quotRem` 60
disp = artist ++ " - " ++ title ++ " (-"++(show minutes)++":"++(show seconds)++")" -- will be wrong if seconds < 10
audcolor False = dzenColor base0 base03
audcolor True = dzenColor base1 base02
return $ wrap "^ca(1, pms p)" "^ca()" (audcolor ispaused disp)
return $ either (const Nothing) Just info
So I can stick that in ppExtras and it works fine—except it only gets run when the logHook gets run, and that happens only when a suitable event comes down the pike. So the display is potentially static for a long time, until I (e.g.) switch workspaces.
It seems like some people just run two dzen bars, with one getting output piped in from a shell script. Is that the only way to have regular updates? Or can this be done from within xmonad (without getting too crazy/hacky)?
ETA: I tried this, which seems as if it should work better than it does:
create a TChan for updates from XMonad, and another for updates from a function polling Audacious;
set the ppOutput field in the PP structure from DynamicLog to write to the first TChan;
fork the audacious-polling function and have it write to the second TChan;
fork a function to read from both TChans (checking that they aren't empty, first), and combining the output.
Updates from XMonad are read from the channel and processed in a timely fashion, but updates from Audacious are hardly registered at all—every five or so seconds at best. It seems as if some approach along these lines ought to work, though.
I know this is an old question, but I came here looking for an answer to this a few days ago, and I thought I'd share the way I solved it. You actually can do it entirely from xmonad. It's a tiny bit hacky, but I think it's much nicer than any of the alternatives I've come across.
Basically, I used the XMonad.Util.Timer library, which will send an X event after a specified time period (in this case, one second). Then I just wrote an event hook for it, which starts the timer again, and then manually runs the log hook.
I also had to use the XMonad.Util.ExtensibleState library, because Timer uses an id variable to make sure it's responding to the right event, so I have to store that variable between events.
Here's my code:
{-# LANGUAGE DeriveDataTypeable #-}
import qualified XMonad.Util.ExtensibleState as XS
import XMonad.Util.Timer
...
-- wrapper for the Timer id, so it can be stored as custom mutable state
data TidState = TID TimerId deriving Typeable
instance ExtensionClass TidState where
initialValue = TID 0
...
-- put this in your startupHook
-- start the initial timer, store its id
clockStartupHook = startTimer 1 >>= XS.put . TID
-- put this in your handleEventHook
clockEventHook e = do -- e is the event we've hooked
(TID t) <- XS.get -- get the recent Timer id
handleTimer t e $ do -- run the following if e matches the id
startTimer 1 >>= XS.put . TID -- restart the timer, store the new id
ask >>= logHook.config -- get the loghook and run it
return Nothing -- return required type
return $ All True -- return required type
Pretty straightforward. I hope this is helpful to someone.
It cannot be done from within xmonad; xmonad's current threading model is a bit lacking (and so is dzen's). However, you can start a separate process that periodically polls your music player and then use one of the dzen multiplexers (e.g. dmplex) to combine the output from the two processes.
You may also want to look into xmobar and taffybar, which both have better threading stories than dzen does.
With regards to why your proposed TChan solution doesn't work properly, you might want to read the sections "Conventions", "Foreign Imports", and "The Non-Threaded Runtime" at my crash course on the FFI and gtk, keeping in mind that xmonad currently uses GHC's non-threaded runtime. The short answer is that xmonad's main loop makes an FFI call to Xlib that waits for an X event; this call blocks all other Haskell threads from running until it returns.

Command line options picked up by criterion library

I have used the libraries criterion and cmdargs.
When I compile the program completely without cmdargs and run it e.g. ./prog --help then I get some unwanted response from criterion about the possible options and the number of runs etc..
When I compile and run it as below the command line options are first picked up by my code then then read by criterion. Criterion then subsequently reports and error telling me that the option --byte is unknown. I have not seen anything in the criterion documentation how this could be switched off or worked around. Is there a way to clear out the command line options ofter I have read them? Otherwise I would need to use e.g. CPUTime instead of criterion, that is OK to me since I do to really require the loads of extra functionality and data that criterion delivers.
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveDataTypeable #-}
import System.Console.CmdArgs
data Strlen = Strlen {byte :: Int} deriving (Data, Typeable, Show)
strlen = cmdArgsMode $ Strlen {byte = def} &= summary "MessagePack benchmark v0.04"
main = do
n <- cmdArgsRun strlen
let datastring = take (byte n) $ randomRs ('a','z') (mkStdGen 3)
putStrLn "Starting..."
conn <- connect "192.168.35.62" 8081
defaultMain [bench "sendReceive" $ whnfIO (mywl conn datastring)]
Use System.Environment.withArgs. Parse the command line arguments first with cmdArgs, then pass what you haven't used to criterion:
main = do
(flags, remaining) <- parseArgsHowever
act according to flags
withArgs remaining $
defaultMain [ ... ]
Take a look at the criterion source. You should be able to write your own defaultMainWith function that handles args however you want, including ignoring them, or ignoring unknown args, or etc...

Resources