In a previous post, I had written about [Folding in Haskell](/2012/12/27/folding-in-haskell.html] which in itself is a very powerful tool. We spent a brief moment in that tutorial actually working through a problem and writing the folding process out long hand.
Well, scanning scanl and scanr does this for you! It shows you the reduction steps in the form of an array returned back to you.
Sometimes, Haskell’s syntax is so alien to read (to my eyes at least anyway). I’ve seen wide-spread use of the $ operator all over lots of people’s code and never really had a grasp on what it is/does. In the end, it’s really quite simple. The whitespace character has a very high precedence order, so when you’re using spaces the precedence order looks like this.
fabc=((fa)b)c
This is classified as being left-associative. In contrast, using the $ operator allows us to be right-associative. An example.
f$a$b$c=f(a(bc))
Looking at this, it’s starting to look very much how our programming languages are structured with function calls. We’re very right-associative. Because Haskell uses the white space character to denote left-associations, it takes a lot of parenthesis to make a complex state right-associative as you need to change the precedence order by hand. This is the true power of the $ function. We can use $ to free us from parenthesising everything, so that a transformation as below occurs.
putStrLn(shownum)putStrLn$shownum
This simple scenario doesn’t illustrate exactly how much $ will help us out. Here’s another slightly more complex scenario. It becomes clear here that $ is working to make our code more readable.
sum(take10(cycle[1,2,3]))sum$take10$cycle[1,2,3]
In character-space length they’re equivalent, but the second version looks less LISP-y. I guess this is what was being aimed at.
Seems I’m forever making card games in Haskell, so it only seemed right that I try and make a library of routines and data types that will get me going quicker. Don’t get me wrong, I intend on doing something serious with Haskell one day - I just seriously lack the chops to do so right now.
As with any development process, you as a developer should write unit tests. Not only is it good practice but it also gives you a repeatable base of executions to assure you that the last change you put in won’t break your masterpiece. Today I want to talk about the QuickCheck unit testing library for Haskell.
What are we testing?
To give you an idea of the playing field we’re on, I’ll just post some of the simple routines that I have done so far. First up is the data types that will help us represent a single playing card.
-- | Card values for a standard deck dataCardValue=Ace|Two|Three|Four|Five|Six|Seven|Eight|Nine|Ten|Jack|Queen|Kingderiving(Show,Eq,Enum)-- | Possible card suits dataCardSuit=Heart|Diamond|Club|Spadederiving(Show,Eq,Enum)-- | A card dataCard=CardCardValueCardSuitderiving(Show,Eq)
A card has a suit and a value. Pretty straight forward. I could have made a type that wrapped an array of the Card type and called it Deck, but I’m happy just handling an array of Card. Now to build a deck and to shuffle it!
-- | Seeds a list of cards with a random value seedCards::StdGen->[Card]->[(Card,Int)]seedCardsg[]=[]seedCardsg(c:cs)=x:seedCardsngcswhere(seed,ng)=randomR(1,10000)g::(Int,StdGen)x=(c,seed)-- | Makes an ordered deck of cards makeDeck::[Card]makeDeck=[Cardvs|v<-[Ace..King],s<-[Heart..Spade]]-- | Makes a randomly shuffled deck of cards makeShuffledDeck::StdGen->[Card]makeShuffledDeckg=[x|c<-sorted,letx=fstc]wherecards=seedCardsgmakeDecksorted=sortBy(compare`on`snd)cards
When a deck is built with makeDeck the cards are ordered just like they are when you open a fresh deck of cards, so we need to shuffle them in order to make this game any fun! seedCards assigns a random value to each card that it is passed and then makeShuffledDeck saves the day by ordering by this random seed to give a shuffled deck.
That’s all pretty simple still and that’s where the “testable” parts stop. So, still the question: what are we testing? Well, I’m sure there are plenty of other scenarios, but for today’s purposes we’ll test the following:
Are there 52 cards in a deck made by makeDeck?
Are there still 52 cards in a deck after they’ve been processed by makeShuffledDeck?
Is the deck made by makeDeck not in the same order as the deck made by makeShuffledDeck?
Great. With these three scenarios in mind, here’s how easy it is to assert these facts using QuickCheck.
Hold on!100 tests? We only defined 3 tests though. How can this be? You’ll see that for the second and third tests actually have an anonymous function passed to them. Because both of these depend on a random number generator (to shuffle the deck), I’ve passed in mkStdGen’s integer that it maps to a generator from the function’s parameter list. QuickCheck grabbed hold of this and rather than just running 1 test, it went ahead and gave the anonymous function 100 random values. That’s much better coverage for what is seemingly the cost of defining the test as an anonymous method. Immediately you can see the power of unit testing with such a simple framework and how you can be productive relatively quickly.
Being able to use parts of code that you have written in different languages in your environment of choice is a great productivity booster. For those particular problems you can really pick the tool that you need. Haskell and C are no exception to this. The Haskell website has a great little write-up on the topic. In today’s post, I’m going to run you through the steps that I followed to get this running.
Write your Haskell
The compilation process depends on your Haskell code being written first as GHC will generate some stub code for you. Here’s a very simple and crude prime number tester:
{- LANGUAGE ForeignFunctionInterface #-}modulePrimewhereimportForeign.C.Types-- | Take a boolean and convert it to an integerbool_to_int::Bool->Intbool_to_intFalse=0bool_to_intTrue=1-- | Brute force division style prime number testingis_prime::Int->Intis_primex=bool_to_intptestwheredivisible=[n|n<-[3,5..(x-1)],x`mod`n==0]ptest=length(divisible)==0-- | Interface exposed into C landis_prime_hs::CInt->CIntis_prime_hs=fromIntegral.is_prime.fromIntegral-- | Export symbols into C land foreignexportccallis_prime_hs::CInt->CInt
Ignoring my method of primes testing, you can see some interesting pieces in this Haskell source. On the first line we’re enabling a GHC extension for the ForeignFucntionInterface. This allows us to export symbols to other languages. We have our implementation actually in the function is_prime with is_prime_hs being the callable wrapper from outside, in this case C. The last line actually exports our wrapper as a callable function.
Haskell compilation
You’ve got your Haskell module ready for compilation, but it’s going to be a little bit different. This source is supporting another application rather than containing a main function of its own.
$ ghc -c-O prime.hs
This command will compile our file only -c and optimise -O. A stub header file is generated for us (thanks to our FFI instructions on the first line of our Haskell file) that we can include in our main program.
Write your C
It’s now time to call our prime function. There is a little bit of administration fluff that we have to go through in order to get there, but it’s really not much to worry about. Take note that we’re including our stub header file that was generated for us in our Haskell compilation step.
#include<HsFFI.h>
#ifdef __GLASGOW_HASKELL__
#include"Prime_stub.h"externvoid__stginit_Prime(void);#endif
#include<stdio.h>intmain(intargc,char*argv[]){inti;/* FFI initialization */hs_init(&argc,&argv);#ifdef __GLASGOW_HASKELL__
hs_add_root(__stginit_Prime);#endif
/* determine if 13 is prime */i=is_prime_hs(13);printf("is 13 prime? %d\n",i);/* determine if 21 is prime */i=is_prime_hs(21);printf("is 21 prime? %d\n",i);/* teardown FFI */hs_exit();return0;}
So that’s pretty straight-forward C code in the end. It’s a little awkward at first to look at the #define rigmarole at the top of the file, but you’ll soon see straight past it. You can see at the top of the file that we’ve got an external symbol representing the module, Primes. This is used as a secondary initialisation step after we start up FFI (with hs_init). The call to hs_add_root is the extra initialisation required (per module we import - I’m led to believe) that we do for GHC’s sake. Your C code is written, it’s now time to compile, link and execute! Compilation to produce an executable looks like this.
$ ghc --make-no-hs-main-optc-O call_prime.c Prime -otest
We’re telling ghc that we want to make --make our executable -o test that doesn’t have a main routine in haskell source -no-hs-main and optimised by the c compiler -optc-O. We should have an executable, ready to go: