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.
Related
I have a 'QuasiQuoter' which is useful in source code in Haskell, but also as a standalone application. So, I need to be able to run QuasiQuoter
During the compile time in Haskell - [myGrammar|someCommand|]
In runtime (runtime compilation) in shell - mygrammar 'someCommand'
The first part is easy but the second part might be a little clumsy if solved as calling the compiler with some generated code from the runtime.
I would like to solve a second part of the problem using some nice method in Haskell which doesn't accept only the source code, but accepts QuasyQuoter datatype instead so the code is less clumsy. But I can't find any compilation method like that.
Do you know any? Thanks.
Example of usage
Haskell
The function takes tuple [(a,b,c,d,e)] and returns a list of the strings with the products.
function = [lsql| {1..5}, r=[ a.* |> (*) ], "Product of a.1 * a.2 * ... * a.5 is &a.r"|]
Bash
The command reads from stdin csv with at least 5 numerical columns and returns a list of their products (one per line).
lsql-csv '-, r=[ a.* |> (*) ], "Product of a.1 * a.2 * ... * a.5 is &a.r"'
I think the question is how to parse and process a string in a uniform way between a quasiquoter and some other chunk of code. If this interpretation is right, then you just... do that. For example:
-- implementation of these is left to the reader, but can use standard Haskell
-- programming techniques and libraries, like parsec and ADTs and stuff
command :: Parser Command
interpret :: Command -> IO ()
jit :: Command -> Exp -- or Q Exp
Then, in your lsql-csv.hs, you would write something like
main = do
[s] <- getArgs
case parse command s of
Left err -> die (show err)
Right com -> interpret com
and in your LSql/CSV/QQ.hs, you would write something like
lsql = QuasiQuoter { quoteExp = \s -> case parse command s of
Left err -> qReport True (show err) >> fail ""
Right com -> return (jit com) -- or just jit com if that's already a Q Exp
}
I'm doing some very simple performance testing of a simple function that I believe has O(n)(squared) performance (or worse).
Currently I'm running multiple statements which is tedious to repeat:
ghci> myfunction 0 100
true
ghci> myfunciton 0 200
true
ghci> myfunction 0 300
true
ghci> :r
Is there a way I can run all four GHCi statements? I can't just combine them using "native" Haskell as I'd like to include the :r (which is a GHCi statement - not exactly Haskell) that gets run at the end.
One way I've found is creating a separate file:
myfunction 0 100
myfunction 0 200
myfunction 0 300
:r
and then using:
:script path/to/file
You can define a custom GHCi command using :def in this way:
> :def foo (\_ -> return "print 100\nprint 200\n:t length")
> :foo
100
200
length :: Foldable t => t a -> Int
In the returned string, :-commands can be included as well, like :t above.
One way of doing it is to create a testing suite in your Cabal file in which you place your function calls as tests, then use stack test --file-watch. That recompiles and reruns the tests every time you save a file.
I am using Haskell and Parsec to parse a file format. My parsing function looks something like:
parseInput :: String -> Model
parseInput input = ...
data Model = Model { mNumV :: Int, mNumF :: Int, ... }
In order to test this, I am using QuickCheck. I have defined an Arbitrary instance that generates a String representing the contents of a formatted file:
instance Arbitrary File where
arbitrary = ...
data File = File { fContents :: String, fNumV :: Int, fNumF :: Int, ... }
One of my properties might check to determine if mNumV == fNumV after parsing the arbitrary String. This works well - when it works.
But if something fails, Parsec throws an error similar to:
*** Failed (after 1 test):
Exception:
(line 302, column 3):
unexpected "\n"
expecting space
This is useful - however, after the test fails the contents of the arbitrary file disappear. I can't go in and reference line 302.
The only alternative that I can see is to print the fContents of each arbitrary file after each test - but that seems like a terrible idea. The same goes for routing every arbitrary file to a file on disk for later reference.
Is there a common way around this?
You can use whenFail to print the offending string (or dump it to a file) upon failure.
I have an assignment which is to create a calculator program in Haskell. For example, users will be able to use the calculator by command lines like:
>var cola =5; //define a random variable
>cola*2+1;
(print 11)
>var pepsi = 10
>coca > pepsi;
(print false)
>def coke(x,y) = x+y; //define a random function
>coke(cola,pepsi);
(print 15)
//and actually it's more complicated than above
I have no clue how to program this in Haskell. All I can think of right now is to read the command line as a String, parse it into an array of tokens. Maybe go through the array, detect keywords such "var", "def" then call functions var, def which store variables/functions in a List or something like that. But then how do I store data so that I can use them later in my computation?
Also am I on the right track because I am actually very confused what to do next? :(
*In addition, I am not allowed to use Parsec!*
It looks like you have two distinct kinds of input: declarations (creating new variables and functions) and expressions (calculating things).
You should first define some data structures so you can work out what sort of things you are going to be dealing with. Something like:
data Command = Define Definition | Calculate Expression | Quit
type Name = String
data Definition = DefVar Name Expression | DefFunc Name [Name] Expression
-- ^ alternatively, implement variables as zero-argument functions
-- and merge these cases
data Expression = Var Name | Add Expression Expression | -- ... other stuff
type Environment = [Definition]
To start off with, just parse (tokenise and then parse the tokens, perhaps) the stuff into a Command, and then decide what to do with it.
Expressions are comparatively easy. You assume you already have all the definitions you need (an Environment) and then just look up any variables or do additions or whatever.
Definitions are a bit trickier. Once you've decided what new definition to make, you need to add it to the environment. How exactly you do this depends on how exactly you iterate through the lines, but you'll need to pass the new environment back from the interpreter to the thing which fetches the next line and runs the interpreter on it. Something like:
main :: IO ()
main = mainLoop emptyEnv
where
emptyEnv = []
mainLoop :: Environment -> IO ()
mainLoop env = do
str <- getLine
case parseCommnad str of
Nothing -> do
putStrLn "parse failed!"
mainLoop env
Just Quit -> do
return ()
Just (Define d) -> do
mainLoop (d : env)
Just (Calculate e) -> do
putStrLn (calc env e)
mainLoop env
-- the real meat:
parseCommand :: String -> Maybe Command
calc :: Environment -> Expression -> String -- or Integer or some other appropriate type
calc will need to look stuff up in the environment you create as you go along, so you'll probably also need a function for finding which Definition corresponds to a given Name (or complaining that there isn't one).
Some other decisions you should make:
What do I do when someone tries to redefine a variable?
What if I used one of those variables in the definition of a function? Do I evaluate a function definition when it is created or when it is used?
These questions may affect the design of the above program, but I'll leave it up to you to work out how.
First, you can learn a lot from this tutorial for haskell programming
You need to write your function in another doc with .hs
And you can load the file from you compiler and use all the function you create
For example
plus :: Int -> Int -- that mean the function just work with a number of type int and return Int
plus x y = x + y -- they receive x and y and do the operation
I just started with Haskell and tried to do write some tests first. Basically, I want to define some function and than call this function to check the behavior.
add :: Integer -> Integer -> Integer
add a b = a+b
-- Test my function
add 2 3
If I load that little script in Hugs98, I get the following error:
Syntax error in declaration (unexpected `}', possibly due to bad layout)
If I remove the last line, load the script and then type in "add 2 3" in the hugs interpreter, it works just fine.
So the question is: How can I put calls of my functions in the same script as the function definition? I just want to load the script and be able to check if it does what I expect it to...I don't want to type them in manually all the time.
Others have said how to solve your immediate problem, but for testing you should be using QuickCheck or some other automated testing library.
import Test.QuickCheck
prop_5 = add 2 3 == 5
prop_leftIdentity n = add 0 n == n
Then run quickCheck prop_5 and quickCheck prop_leftIdentity in your Hugs session. QuickCheck can do a lot more than this, but that will get you started.
(Here's a QuickCheck tutorial but it's out of date. Anyone know of one that covers QuickCheck 2?)
the most beginner friendly way is probably the doctest module.
Download it with "cabal install doctest", then put your code into a file "Add.hs" and run "doctest Add.hs" from the command line.
Your code should look like this, the formatting is important:
module Add where
-- | add adds two numbers
--
-- >>> add 2 3
-- 5
-- >>> add 5 0
-- 5
-- >>> add 0 0
-- 0
add :: Integer -> Integer -> Integer
add a b = a+b
HTH Chris
Make a top level definition:
add :: Integer -> Integer -> Integer
add a b = a + b
test1 = add 2 3
Then call test1 in your Hugs session.
How can I put calls of my functions in the same script as the function definition? I just want to load the script and be able to check if it does what I expect it to...I don't want to type them in manually all the time.
In short, you can't. Wrap it in a function and call it instead. Your file serves as a valid Haskell module, and having "flying" expression is not a valid way to write it.
You seem to come from a scripting language background, but don't try treating Haskell as one of them.
If you have ghc installed, then the runhaskell command will interpret and run the main function in your file.
add x y = x + y
main = print $ add 2 3
Then on the command line
> runhaskell Add.hs
5
Not sure, but hugs probably has a similar feature to the runhaskell command. Or, if you load the file into the hugs interpreter, you can simply run it by calling main.
I was trying to do the same thing and I just made a function that ran through all my test cases (using guards) and returned 1 if they all passed and threw an error if any failed.
test :: Num b => a->b
test x
| sumALL [1] /= 1 = error "test failed"
| sumALL [0,1,2] /= 3 = error "test failed"
...
| otherwise = 1