seeking lore of the QuickCheck masters
I am playing around with an implementation of a little language, and I would like to use QuickCheck to test my code. My problem is that I want to test only well-typed terms. I don't know how to craft my `arbitrary' functions so that the probability of generating a well-typed term is more than vanishingly small. Can anybody pass on interesting tips and tricks that might help? Norman
nr@eecs.harvard.edu (Norman Ramsey) writes:
I am playing around with an implementation of a little language, and I would like to use QuickCheck to test my code. My problem is that I want to test only well-typed terms. I don't know how to craft my `arbitrary' functions so that the probability of generating a well-typed term is more than vanishingly small. Can anybody pass on interesting tips and tricks that might help?
You want a generator that can produce an arbitrary code fragment, *given* what type you want it to have. So first, generate an arbitrary type, then generate an arbitrary expression for it. Assuming that your little language is sort-of functional, then to generate a code fragment for a given type, say Int, you might have the following choices: * Generate a literal value :: Int * Generate a conditional. e.g. if <arbitrary :: Bool> then <arbitrary :: Int> else <arbitrary :: Int> * Generate a case. e.g. case <arbitrary :: a> of <arbitrary pattern :: a> -> <arbitrary :: Int> <arbitrary pattern :: a> -> <arbitrary :: Int> * and so on for other language constructs. * Generate an application of a unary function :: ArbitraryType a => a -> Int or perhaps :: ArbitraryTypeInvolving Int a => a -> Int to a value of the constrained type. * Generate an application of a binary function :: (ArbitraryType a) => a -> (a -> Int) or :: (ArbitraryType a, ArbitraryType b) => a -> (b -> Int) or :: (ArbitraryTypeInvolving Int a) => a -> (a -> Int) or :: (ArbitraryTypeInvolving Int a, ArbitraryType b) => a -> (b -> Int) or :: (ArbitraryTypeInvolving Int b, ArbitraryType a) => a -> (b -> Int) to a value of the constrained type. * and so on for more complex types. It is quite a lot trickier than this little sketch, I'm sure, but I hope this helps to spark some more ideas. Regards, Malcolm
On Tue, 15 Apr 2003, Malcolm Wallace wrote:
nr@eecs.harvard.edu (Norman Ramsey) writes:
I am playing around with an implementation of a little language, and I would like to use QuickCheck to test my code. My problem is that I want to test only well-typed terms. I don't know how to craft my `arbitrary' functions so that the probability of generating a well-typed term is more than vanishingly small. Can anybody pass on interesting tips and tricks that might help?
You want a generator that can produce an arbitrary code fragment, *given* what type you want it to have. So first, generate an arbitrary type, then generate an arbitrary expression for it.
Assuming that your little language is sort-of functional, then to generate a code fragment for a given type, say Int, you might have the following choices:
* Generate a literal value :: Int * Generate a conditional. e.g. if <arbitrary :: Bool> then <arbitrary :: Int> else <arbitrary :: Int> * Generate a case. e.g. case <arbitrary :: a> of <arbitrary pattern :: a> -> <arbitrary :: Int> <arbitrary pattern :: a> -> <arbitrary :: Int> * and so on for other language constructs. * Generate an application of a unary function :: ArbitraryType a => a -> Int or perhaps :: ArbitraryTypeInvolving Int a => a -> Int to a value of the constrained type. * Generate an application of a binary function :: (ArbitraryType a) => a -> (a -> Int) or :: (ArbitraryType a, ArbitraryType b) => a -> (b -> Int) or :: (ArbitraryTypeInvolving Int a) => a -> (a -> Int) or :: (ArbitraryTypeInvolving Int a, ArbitraryType b) => a -> (b -> Int) or :: (ArbitraryTypeInvolving Int b, ArbitraryType a) => a -> (b -> Int) to a value of the constrained type. * and so on for more complex types.
It is quite a lot trickier than this little sketch, I'm sure, but I hope this helps to spark some more ideas.
Regards, Malcolm
Yes, this is how I would do it. Then, of course, it's important to control the size of the generated terms. I would write a sized generator dividing the size between sub-expressions, and restricting expressions to be lambdas, constants or variables when the size reaches zero. John
Hello again guys. I have made a small program that basically all it does is read a text file and write another text file with the info from the first one. Now let's say I have a bin file and I want the program to still write the text file and also create this bin file. Is it possible to build in this bin file inside the program so everything is inside the executable file (exe) and then when the user runs the program it does it job (write the text file) and also creates this bin file exactly like it was on the same directory the program is being run. Basically I just want this so that the user doesn't have to download anything else than the exe file to be able to run the program fully (the text files and bin files are to be used with another program)??? Best Regards NooK
"Alexandre Weffort Thenorio" <alethenorio@home.se> writes:
Is it possible to build in this bin file inside the program so everything is inside the executable file (exe)
You can find a C/linker magic solution at http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&safe=off&selm=20020520053... See also http://www.gsp.com/cgi-bin/man.cgi?section=1&topic=file2c You probably need FFI to make use of these. Feri.
Hmm I am not very good at C so is it just not possible to do it with plain haskell, that is, isn't there any haskell function like File2C that does that?? Best Regards NooK ----- Original Message ----- From: "Ferenc Wagner" <wferi@tba.elte.hu> To: <haskell@haskell.org> Sent: Tuesday, April 29, 2003 4:49 PM Subject: Re: Is it possible to build in a file in a haskell program??
"Alexandre Weffort Thenorio" <alethenorio@home.se> writes:
Is it possible to build in this bin file inside the program so everything is inside the executable file (exe)
You can find a C/linker magic solution at
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&safe=off&selm=20020520053 155.5B2FD39FC%40overcee.wemm.org
See also http://www.gsp.com/cgi-bin/man.cgi?section=1&topic=file2c
You probably need FFI to make use of these. Feri. _______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
"Alexandre Weffort Thenorio" <alethenorio@home.se> writes:
Hmm I am not very good at C so is it just not possible to do it with plain haskell, that is, isn't there any haskell function like File2C that does that??
There are several binary modules for Haskell, but they are nonstandard, and I do not know if any of them will do what you want. Search the archives to get an overview! Feri.
Hello again guys. I have made a small program that basically all it does is read a text file and write another text file with the info from the first one. Now let's say I have a bin file and I want the program to still write the text file and also create this bin file. Is it possible to build in this bin file inside the program so everything is inside the executable file (exe) and then when the user runs the program it does it job (write the text file) and also creates this bin file exactly like it was on the same directory the program is being run.
Yes, of course. What you want to do is first write a Haskell (or Perl) program that reads in a file and translates it into a little Haskell program, like this: module MyBinFile ( mybinfile ) where mybinfile :: String mybinfile = "Hello, world\x0A\x1A\x00\x01\x02\ \\x03\x04\x05.....\ \......\x00\x00" (the string continuation syntax is defined in the Haskell report, as are the standard string escapes for characters outside \x20..\x7E) Then your main program looks like this: module Main where import MyBinFile ( mybinfile ) import IO main = do h <- ... open the file you want ... hPutStr h mybinfile hClose h So you run your Haskell/Perl script on the original file to generate the Haskell file MyBinFile.hs, then you compile MyBinFile.hs and Main.hs, and distribute the resulting binary. Warning: compilation may be a bit slow with such a large string. Alternatively, you could get even trickier, by using the linker to stick your original bin file onto the end of the executable. Then you could just open the executable file itself in Haskell, find the bin file, and read it out. You coudl either interpret the ELF/EXE binary format, or just look for a magic string (careful you don't find the pattern in your search code rather than the marker you want to find!). Let us know how you get on. HTH. --KW 8-) -- Keith Wansbrough <kw217@cl.cam.ac.uk> http://www.cl.cam.ac.uk/users/kw217/ University of Cambridge Computer Laboratory.
Thanks but I am not sure what exactly you mean. I've done this: Created a file called MyBinFile.hs and added such code: module MyBinFile ( mybinfile ) where mybinfile :: String mybinfile = "Hello, world\x0A" Created file Main.hs and added such code module Main where import MyBinFile ( mybinfile ) import IO main = do h <- readFile file.bin hPutStr h mybinfile hClose h Tried compiling main.hs file but it says "Failed to load interface for MyBinFile". Sorry but I am not what you can call a experienced programmer but if I understood right I can read the bin file with haskell getting some kind of binary string. The I can just add this binary string into my program and tell it to write a file (In binary mode Using IoExts module) using this String. Otherwise could you be a bit more specific?? Best Regards Alex ----- Original Message ----- From: "Keith Wansbrough" <Keith.Wansbrough@cl.cam.ac.uk> To: "Alexandre Weffort Thenorio" <alethenorio@home.se> Cc: <haskell@haskell.org> Sent: Tuesday, April 29, 2003 6:17 PM Subject: Re: Is it possible to build in a file in a haskell program??
Hello again guys. I have made a small program that basically all it does is read a text file and write another text file with the info from the first one. Now let's say I have a bin file and I want the program to still write the text file and also create this bin file. Is it possible to build in this bin file inside the program so everything is inside the executable file (exe) and then when the user runs the program it does it job (write the text file) and also creates this bin file exactly like it was on the same directory the program is being run.
Yes, of course.
What you want to do is first write a Haskell (or Perl) program that reads in a file and translates it into a little Haskell program, like this:
module MyBinFile ( mybinfile ) where mybinfile :: String mybinfile = "Hello, world\x0A\x1A\x00\x01\x02\ \\x03\x04\x05.....\ \......\x00\x00"
(the string continuation syntax is defined in the Haskell report, as are the standard string escapes for characters outside \x20..\x7E)
Then your main program looks like this:
module Main where import MyBinFile ( mybinfile ) import IO
main = do h <- ... open the file you want ... hPutStr h mybinfile hClose h
So you run your Haskell/Perl script on the original file to generate the Haskell file MyBinFile.hs, then you compile MyBinFile.hs and Main.hs, and distribute the resulting binary.
Warning: compilation may be a bit slow with such a large string.
Alternatively, you could get even trickier, by using the linker to stick your original bin file onto the end of the executable. Then you could just open the executable file itself in Haskell, find the bin file, and read it out. You coudl either interpret the ELF/EXE binary format, or just look for a magic string (careful you don't find the pattern in your search code rather than the marker you want to find!).
Let us know how you get on.
HTH.
--KW 8-)
-- Keith Wansbrough <kw217@cl.cam.ac.uk> http://www.cl.cam.ac.uk/users/kw217/ University of Cambridge Computer Laboratory.
OK. Here is what happen. I wrote the small haskell program that write another haskell program containing a string representation of the bin file. If use openFile function the string representation is not complete (Doesn't write the whole bin file, bug maybe) but if I use openFileEx (IOExts Library, Lang Package) it writes the whole thing BUT both ways it still gives me a file with a binary string representation (Weird sings) like: module MyBinFile ( mybinfile ) where mybinfile :: String mybinfile = "Ì þs$>Ì Ì þVÌ 01o ¦·?sfÌ{%z-æÇdæÇe_ Æe\\\\ÃàQ'%Ñàz&òÆdÑày&çÖà{ÇdÖà|Çez-ÆdçÆeç? 00 0...." thus of course giving me a error in character literal in third line when trying to run the old main (That is gonna rewrite the bin file). Any ideas?? Best Regards Alex
Alexandre Weffort Thenorio wrote:
OK. Here is what happen. I wrote the small haskell program that write another haskell program containing a string representation of the bin file.
If use openFile function the string representation is not complete (Doesn't write the whole bin file, bug maybe) but if I use openFileEx (IOExts Library, Lang Package) it writes the whole thing
BUT both ways it still gives me a file with a binary string representation (Weird sings) like:
module MyBinFile ( mybinfile ) where mybinfile :: String mybinfile = "Ì þs$>Ì Ì þVÌ 01o ¦·?sfÌ{%z-æÇdæÇe_ Æe\\\\ÃàQ'%Ñàz&òÆdÑày&çÖà{ÇdÖà|Çez-ÆdçÆeç? 00 0...."
thus of course giving me a error in character literal in third line when trying to run the old main (That is gonna rewrite the bin file). Any ideas??
Use "show", e.g. hPutStrLn outFile $ "mybinfile = " ++ show theString -- Glynn Clements <glynn.clements@virgin.net>
Thanks a lot guys. "Show" seems to have solved the problem. The only weird thing is that created file is not exactly the same size (100 bytes bigger) but hopefully that should not be a problem. Just would like to point that openFile function from IO library did not write the right string representation (Just small part of it) while openFileEx in IOExts library did write the whole thing. Maybe it is a bug? As a last question I am curious about a thing you guys typed a lot latelly, What does the $ sign (Dollar) does?? Thanks again Alex ----- Original Message ----- From: "Glynn Clements" <glynn.clements@virgin.net> To: "Alexandre Weffort Thenorio" <alethenorio@home.se> Cc: "Keith Wansbrough" <Keith.Wansbrough@cl.cam.ac.uk>; <haskell@haskell.org> Sent: Wednesday, April 30, 2003 6:16 AM Subject: Re: Is it possible to build in a file in a haskell program?? Alexandre Weffort Thenorio wrote:
OK. Here is what happen. I wrote the small haskell program that write another haskell program containing a string representation of the bin file.
If use openFile function the string representation is not complete (Doesn't write the whole bin file, bug maybe) but if I use openFileEx (IOExts Library, Lang Package) it writes the whole thing
BUT both ways it still gives me a file with a binary string representation (Weird sings) like:
module MyBinFile ( mybinfile ) where mybinfile :: String mybinfile = "Ì þs$>Ì Ì þVÌ 01o ¦·?sfÌ{%z-æÇdæÇe_ Æe\\\\ÃàQ'%Ñàz&òÆdÑày&çÖà{ÇdÖà|Çez-ÆdçÆeç? 00 0...."
thus of course giving me a error in character literal in third line when trying to run the old main (That is gonna rewrite the bin file). Any ideas??
Use "show", e.g. hPutStrLn outFile $ "mybinfile = " ++ show theString -- Glynn Clements <glynn.clements@virgin.net>
On Wed, 30 Apr 2003 15:29:05 +0200 "Alexandre Weffort Thenorio" <alethenorio@home.se> wrote:
Thanks a lot guys. "Show" seems to have solved the problem. The only weird thing is that created file is not exactly the same size (100 bytes bigger) but hopefully that should not be a problem. Just would like to point that openFile function from IO library did not write the right string representation (Just small part of it) while openFileEx in IOExts library did write the whole thing. Maybe it is a bug? As a last question I am curious about a thing you guys typed a lot latelly, What does the $ sign(Dollar) does??
Thanks again
Alex
If the file is opened in text mode it will stop at the first EOF character in the output. I imagine that that was the problem with openFile. $ is just a low precedence right associative function application. It's mainly used to avoid parentheses. It's definition is f $ x = f x. You can change something like f (g (h x)) into f $ g $ x.
Yes you are right (I tested with openFile in TextMode) but as far as I can see openFile cannot be changed to any other mode than TextMode thus openFile does not work with binary files (.bin) whereas openFileEx can be set to BinaryMode instead of TextMode which gives me the right output. Thanks for pointing it out. Why isn't IO and IOExts put together in one library. For example functions like openFile can be rewritten to work the same way as openFileEx thus eliminating one function and making it easier for the user not to have to compile the program with lang package. Best Regards NooK ----- Original Message ----- From: "Derek Elkins" <ddarius@hotpop.com> To: <haskell@haskell.org> Sent: Wednesday, April 30, 2003 3:41 PM Subject: Re: Is it possible to build in a file in a haskell program??
On Wed, 30 Apr 2003 15:29:05 +0200 "Alexandre Weffort Thenorio" <alethenorio@home.se> wrote:
Thanks a lot guys. "Show" seems to have solved the problem. The only weird thing is that created file is not exactly the same size (100 bytes bigger) but hopefully that should not be a problem. Just would like to point that openFile function from IO library did not write the right string representation (Just small part of it) while openFileEx in IOExts library did write the whole thing. Maybe it is a bug? As a last question I am curious about a thing you guys typed a lot latelly, What does the $ sign(Dollar) does??
Thanks again
Alex
If the file is opened in text mode it will stop at the first EOF character in the output. I imagine that that was the problem with openFile.
$ is just a low precedence right associative function application. It's mainly used to avoid parentheses. It's definition is f $ x = f x. You can change something like f (g (h x)) into f $ g $ x.
_______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
On Wed, 30 Apr 2003 15:56:04 +0200 "Alexandre Weffort Thenorio" <alethenorio@home.se> wrote:
Yes you are right (I tested with openFile in TextMode) but as far as I can see openFile cannot be changed to any other mode than TextMode thus openFile does not work with binary files (.bin) whereas openFileEx can be set to BinaryMode instead of TextMode which gives me the right output. Thanks for pointing it out. Why isn't IO and IOExts put together in one library. For example functions like openFile can be rewritten to work the same way as openFileEx thus eliminating one function and making it easier for the user not to have to compile the program with lang package.
Best Regards
NooK
IO is Standard Haskell 98, IOExts are extensions (i.e.non-standard).
I've made a program that just writes a text file. So the user runs the program and it does its job. What I want to do is that when the user runs the program with a flag (Lets say -h) it just shows a text file on the screen with the program explanation (Or better say help file) but otherwise if no flag given the program does it job. The problem is that writing the file on haskell is IO[] (I think) and outputting a text is IO[String] and then haskell doesn't allow me to have a function where it checks if there is flag, creating a text file if not or outputting a String if so because they are different types of output. Can anybody help me here?? Best Regards Alex
On Tue, 29 Apr 2003 15:34:36 +0200 "Alexandre Weffort Thenorio" <alethenorio@home.se> wrote:
I've made a program that just writes a text file. So the user runs the program and it does its job. What I want to do is that when the user runs the program with a flag (Lets say -h) it just shows a text file on the screen with the program explanation (Or better say help file) but otherwise if no flag given the program does it job. The problem is that writing the file on haskell is IO[] (I think) and outputting a text is IO[String] and then haskell doesn't allow me to have a function where it checks if there is flag, creating a text file if not or outputting a String if so because they are different types of output.
Can anybody help me here??
[] isn't a type. Both outputting text and writing to file both have type IO (). (Heck, they are the same function.) Have you tried this? The most straightforward code works. If you have what errors did you get, what's your code?
participants (8)
-
Alexandre Weffort Thenorio -
Derek Elkins -
Ferenc Wagner -
Glynn Clements -
John Hughes -
Keith Wansbrough -
Malcolm Wallace -
nr@eecs.harvard.edu