From 39318169e0b50551db511851829f9337c5fa6313 Mon Sep 17 00:00:00 2001 From: glenda Date: Sun, 15 Nov 2020 15:13:27 +0000 Subject: Import site to git --- sites/pmikkelsen.com/haskell/quine.md | 94 +++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 sites/pmikkelsen.com/haskell/quine.md (limited to 'sites/pmikkelsen.com/haskell') diff --git a/sites/pmikkelsen.com/haskell/quine.md b/sites/pmikkelsen.com/haskell/quine.md new file mode 100644 index 0000000..09a3dcd --- /dev/null +++ b/sites/pmikkelsen.com/haskell/quine.md @@ -0,0 +1,94 @@ +Today I am going to go through the process of writing a small program +which prints it's own source when executed. These kinds of programs are +also called quines, and I suggest that you try it out on your own if you +haven't already done so, as it is a very fun little problem! So if you +don't want any spoilers, please leave this page now and come back later. + + +## First attempt + +Okay, so first of let's just write a small hello world program to get +things going. All our code will be in a file called `quine.hs`. The code +for hello world looks like this + + + main = putStrLn "Hello world!" + + +When this is run using runhaskell quine.hs, it produces the output + + + Hello world! + + +Well, not quite a quine yet but we are getting something to the screen +at least ;) + +## Second attempt + +Now we get the idea that we copy the entire program's source into a +string and print that string instead. To do this, the code could look +something like this + + + main = putStrLn code + where code = "main = putStrLn code\n where code = ???" + + +Here we run into a problem, since we can't include the entire code into +the string. Copying everything we can into the string just increases +the size of the string itself, which means that there is now even more +to copy! We start by only copying all the code upto the string and see +how it looks when executed. The code is now + + + main = putStrLn code + where code = "main = putStrLn code\n where code = " + + +And it outputs + + main = putStrLn code + where code = + +Quite good! Now if we could only include the string itself in its printed form, with the quotes and all, and not the interpreted form with `\n` shown as newlines. + +## Third attempt + +After looking through the haskell standard libraries for a bit, we find +a function that looks promising for what we want to do. This function is +`print`, which prints the output using the `show` function instead of +interpreting the string. We would want to both print it as before, and +to print it using `print`, so we change our main to be `main = putStrLn +code >> print code`, and update our string to include the print. The +code then becomes + + main = putStrLn code >> print code + where code = "main = putStrLn code >> print code\n where code = " + +And it outputs + + + main = putStrLn code >> print code + where code = + "main = putStrLn code >> print code\n where code = " + + +So close! The only problem is that the `putStrLn` append a newline after +the output, which we don't want in this case. + +## Final attempt + +The simple fix is just to use `putStrLn`'s little brother `putStr` +which doesn't print that newline. The final program is then + + + main = putStr code >> print code + where code = "main = putStr code >> print code\n where code = " + +And luckily it outputs exactly itself + + + main = putStr code >> print code + where code = "main = putStr code >> print code\n where code = " + -- cgit v1.2.3