News aggregator

Tom Schrijvers: Leuven Haskell User Group

Planet Haskell - Fri, 03/13/2015 - 2:09am
The Leuven Haskell User Group launched on March 3. The next meeting, titled "The Expression Problem" is due on March 17. The expression problem contrasts strengths and weaknesses of functional and object-oriented programming. We'll see how to solve the problem in Haskell.

Interested? Join us! The meetings are open to everyone.

If you've missed the first meeting, you can catch up on the slides here.

Categories: Offsite Blogs

Functional Jobs: Lead front end developer at Anchor Systems (Full-time)

Planet Haskell - Thu, 03/12/2015 - 6:23pm

Are you a Haskell hacker with plenty of front end development experience? Do you get excited whilst navigating the border between complex back end systems and simple, elegant UIs?

Anchor Systems is looking for a lead front end developer to help us build excellent UIs for our newest products.

You will be working as part of the Anchor R&D group, where we develop systems for cloud orchestration, data visualisation, monitoring and much more. Our R&D developers work exclusively in Haskell. They're great at providing well-documented APIs but we need someone to present this to our users. This is where you come in, bridging the gap between back end and front end.

As our sole (for now) front end developer you will make technical decisions on framework usage, scalable architecture, and abstractions for exposing our back end systems (things like OpenStack, AWS, OAuth) to the user. You will be responsible for the correctness, maintainability and usability of the interfaces you build.

  • You must be an expert in the current HTML5, JS and CSS happenings.

  • You must be comfortable with linux systems.

  • You must be able to architect scalable and highly available front ends.

  • You must have experience working with REST APIs.

  • You should know and love Haskell (or be really interested in learning it).

  • You should have a working knowledge of computer science fundamentals.

  • You should think that usability testing is a great idea.

  • Bonus points for experience with OpenStack, AWS, react.js.

Whilst working with us, you'll find yourself in a great office overlooking Hyde park, with free coffee from a local cafe, a transparent no-nonsense atmosphere and a collaborative academic environment. You'll be sure to learn a lot.

Get information on how to apply for this position.

Categories: Offsite Blogs

Jasper Van der Jeugt: Practical testing in Haskell

Planet Haskell - Thu, 03/12/2015 - 6:00pm

There has been a theme of “Practical Haskell” in the last few blogposts I published, and when I published the last one, on how to write an LRU Cache, someone asked me if I could elaborate on how I would test or benchmark such a module. For the sake of brevity, I will constrain myself to testing for now, although I think a lot of the ideas in the blogpost also apply to benchmarking.

This post is written in Literate Haskell. It depends on the LRU Cache we wrote last time, so you need both modules if you want to play around with the code. Both can be found in this repo.

Since I use a different format for blogpost filenames than GHC expects for module names, loading both modules is a bit tricky. The following works for me:

$ ghci posts/2015-02-24-lru-cache.lhs \ posts/2015-03-13-practical-testing-in-haskell.lhs *Data.SimpleLruCache> :m +Data.SimpleLruCache.Tests *Data.SimpleLruCache Data.SimpleLruCache.Tests>

Alternatively, you can of course rename the files.

Test frameworks in Haskell

There are roughly two kinds of test frameworks which are commonly used in the Haskell world:

  • Unit testing, for writing concrete test cases. We will be using HUnit.

  • Property testing, which allows you to test properties rather than specific cases. We will be using QuickCheck. Property testing is something that might be unfamiliar to people just starting out in Haskell. However, because there already are great tutorials out there on there on QuickCheck, I will not explain it in detail. smallcheck also falls in this category.

Finally, it’s nice to have something to tie it all together. We will be using Tasty, which lets us run HUnit and QuickCheck tests in the same test suite. It also gives us plenty of convenient options, e.g. running only a part of the test suite. We could also choose to use test-framework or Hspec instead of Tasty.

A module structure for tests

Many Haskell projects start out by just having a tests.hs file somewhere, but this obviously does not scale well to larger codebases.

The way I like to organize tests is based on how we organize code in general: through the module hierarchy. If I have the following modules in src/:

AcmeCompany.AwesomeProduct.Database AcmeCompany.AwesomeProduct.Importer AcmeCompany.AwesomeProduct.Importer.Csv

I aim to have the following modules in tests/:

AcmeCompany.AwesomeProduct.Database.Tests AcmeCompany.AwesomeProduct.Importer.Tests AcmeCompany.AwesomeProduct.Importer.Csv.Tests

If I want to add some higher-level tests which basically test the entire product, I can usually add these higher in the module tree. For example, if I wanted to test our entire awesome product, I would write the tests in AcmeCompany.AwesomeProduct.Tests.

Every .Tests module exports a tests :: TestTree value. A TestTree is a tasty concept – basically a structured group of tests. Let’s go to our motivating example: testing the LRU Cache I wrote in the previous blogpost.

Since I named the module Data.SimpleLruCache, we use Data.SimpleLruCache.Tests here.

> {-# OPTIONS_GHC -fno-warn-orphans #-} > {-# LANGUAGE BangPatterns #-} > {-# LANGUAGE GeneralizedNewtypeDeriving #-} > module Data.SimpleLruCache.Tests > ( tests > ) where > import Control.Applicative ((<$>), (<*>)) > import Control.DeepSeq (NFData) > import Control.Monad (foldM_) > import Data.Hashable (Hashable (..)) > import qualified Data.HashPSQ as HashPSQ > import Data.IORef (newIORef, readIORef, writeIORef) > import Data.List (foldl') > import qualified Data.Set as S > import Prelude hiding (lookup) > import Data.SimpleLruCache > import qualified Test.QuickCheck as QC > import qualified Test.QuickCheck.Monadic as QC > import Test.Tasty (TestTree, testGroup) > import Test.Tasty.HUnit (testCase) > import Test.Tasty.QuickCheck (testProperty) > import Test.HUnit (Assertion, (@?=)) What to test

One of the hardest questions is, of course, which functions and modules should I test? If unlimited time and resources are available, the obvious answer is “everything”. Unfortunately, time and resources are often scarce.

My rule of thumb is based on my development style. I tend to use GHCi a lot during development, and play around with datastructures and functions until they seem to work. These “it seems to work” cases I execute in GHCi often make great candidates for simple HUnit tests, so I usually start with that.

Then I look at invariants of the code, and try to model these as QuickCheck properties. This sometimes requires writing tricky Arbitrary instances; I will give an example of this later in this blogpost.

I probably don’t have to say that the more critical the code is, the more tests should be added.

After doing this, it is still likely that we will hit bugs if the code is non-trivial. These bugs form good candidates for testing as well:

  1. First, add a test case to reproduce the bug. Sometimes a test case will be a better fit, sometimes we should go with a property – it depends on the bug.
  2. Fix the bug so the test case passes.
  3. Leave in the test case for regression testing.

Using this strategy, you should be able to convince yourself (and others) that the code works.

Simple HUnit tests

Testing simple cases using HUnit is trivial, so we won’t spend that much time here. @?= asserts that two values must be equal, so let’s use that to check that trimming the empty Cache doesn’t do anything evil:

> testCache01 :: Assertion > testCache01 = > trim (empty 3 :: Cache String Int) @?= empty 3

If we need to some I/O for our test, we can do so without much trouble in HUnit. After all,

Test.HUnit> :i Assertion type Assertion = IO () -- Defined in 'Test.HUnit.Lang'

so Assertion is just IO!

> testCache02 :: Assertion > testCache02 = do > h <- newHandle 10 :: IO (Handle String Int) > v1 <- cached h "foo" (return 123) > v1 @?= 123 > v2 <- cached h "foo" (fail "should be cached") > v2 @?= 123

That was fairly easy.

As you can see, I usually give simple test cases numeric names. Sometimes there is a meaningful name for a test (for example, if it is a regression test for a bug), but usually I don’t mind using just numbers.

Simple QuickCheck tests

Let’s do some property based testing. There are a few properties we can come up with.

Calling HashPSQ.size takes O(n) time, which is why are keeping our own counter, cSize. We should check that it matches HashPSQ.size, though:

> sizeMatches :: (Hashable k, Ord k) => Cache k v -> Bool > sizeMatches c = > cSize c == HashPSQ.size (cQueue c)

The cTick field contains the priority of our next element that we will insert. The priorities currently in the queue should all be smaller than that.

> prioritiesSmallerThanNext :: (Hashable k, Ord k) => Cache k v -> Bool > prioritiesSmallerThanNext c = > all (< cTick c) priorities > where > priorities = [p | (_, p, _) <- HashPSQ.toList (cQueue c)]

Lastly, the size should always be smaller than or equal to the capacity:

> sizeSmallerThanCapacity :: (Hashable k, Ord k) => Cache k v -> Bool > sizeSmallerThanCapacity c = > cSize c <= cCapacity c Tricks for writing Arbitrary instances The Action trick

Of course, if you are somewhat familiar with QuickCheck, you will know that the previous properties require an Arbitrary instance for Cache.

One way to write such instances is what I’ll call the “direct” method. For us this would mean generating a list of [(key, priority, value)] pairs and convert that to a HashPSQ. Then we could compute the size of that and initialize the remaining fields.

However, writing an Arbitrary instance this way can get hard if our datastructure becomes more complicated, especially if there are complicated invariants. Additionally, if we take any shortcuts in the implementation of arbitrary, we might not test the edge cases well!

Another way to write the Arbitrary instance is by modeling use of the API. In our case, there are only two things we can do with a pure Cache: insert and lookup.

> data CacheAction k v > = InsertAction k v > | LookupAction k > deriving (Show)

This has a trivial Arbitrary instance:

> instance (QC.Arbitrary k, QC.Arbitrary v) => > QC.Arbitrary (CacheAction k v) where > arbitrary = QC.oneof > [ InsertAction <$> QC.arbitrary <*> QC.arbitrary > , LookupAction <$> QC.arbitrary > ]

And we can apply these actions to our pure Cache to get a new Cache:

> applyCacheAction > :: (Hashable k, Ord k) > => CacheAction k v -> Cache k v -> Cache k v > applyCacheAction (InsertAction k v) c = insert k v c > applyCacheAction (LookupAction k) c = case lookup k c of > Nothing -> c > Just (_, c') -> c'

You probably guessed where this was going by now: we can generate an arbitrary Cache by generating a bunch of these actions and applying them one by one on top of the empty cache.

> instance (QC.Arbitrary k, QC.Arbitrary v, Hashable k, NFData v, Ord k) => > QC.Arbitrary (Cache k v) where > arbitrary = do > capacity <- QC.choose (1, 50) > actions <- QC.arbitrary > let !cache = empty capacity > return $! foldl' (\c a -> applyCacheAction a c) cache actions

Provided that we can model the complete user facing API using such an “action” datatype, I think this is a great way to write Arbitrary instances. After all, our Arbitrary instance should then be able to reach the same states as a user of our code.

An extension of this trick is using a separate datatype which holds the list of actions we used to generate the Cache as well as the Cache.

> data ArbitraryCache k v = ArbitraryCache [CacheAction k v] (Cache k v) > deriving (Show)

When a test fails, we can then log the list of actions which got us into the invalid state – very useful for debugging. Furthermore, we can implement the shrink method in order to try to reach a similar invalid state using less actions.

The SmallInt trick

Now, note that our Arbitrary instance is for Cache k v, i.e., we haven’t chosen yet what we want to have as k and v for our tests. In this case v is not so important, but the choice of k is important.

We want to cover all corner cases, and this includes ensuring that we cover collisions. If we use String or Int as key type k, collisions are very unlikely due to the high cardinality of both types. Since we are using a hash-based container underneath, hash collisions must also be covered.

We can solve both problems by introducing a newtype which restricts the cardinality of Int, and uses a “worse” (in the traditional sense) hashing method.

> newtype SmallInt = SmallInt Int > deriving (Eq, Ord, Show) > instance QC.Arbitrary SmallInt where > arbitrary = SmallInt <$> QC.choose (1, 100) > instance Hashable SmallInt where > hashWithSalt salt (SmallInt x) = (salt + x) `mod` 10 Monadic QuickCheck

Now let’s mix QuickCheck with monadic code. We will be testing the Handle interface to our cache. This interface consists of a single method:

cached :: (Hashable k, Ord k) => Handle k v -> k -> IO v -> IO v

We will write a property to ensure our cache retains and evicts the right key-value pairs. It takes two arguments: the capacity of the LRU Cache (we use a SmallInt in order to get more evictions), and a list of key-value pairs we will insert using cached (we use SmallInt so we will cover collisions).

> historic > :: SmallInt -- ^ Capacity > -> [(SmallInt, String)] -- ^ Key-value pairs > -> QC.Property -- ^ Property > historic (SmallInt capacity) pairs = QC.monadicIO $ do is used to lift IO code into the QuickCheck property monad PropertyM – so it is a bit like a more concrete version of liftIO. I prefer it here over liftIO because it makes it a bit more clear what is going on.

> h <- $ newHandle capacity

We will fold (foldM_) over the pairs we need to insert. The state we pass in this foldM_ is the history of pairs we previously inserted. By building this up again using :, we ensure history contains a recent-first list, which is very convenient.

Inside every step, we call cached. By using an IORef in the code where we would usually actually “load” the value v, we can communicate whether or not the value was already in the cache. If it was already in the cache, the write will not be executed, so the IORef will still be set to False. We store that result in wasInCache.

In order to verify this result, we reconstruct a set of the N most recent keys. We can easily do this using the list of recent-first key-value pairs we have in history.

> foldM_ (step h) [] pairs > where > step h history (k, v) = do > wasInCacheRef <- $ newIORef True > _ <- $ cached h k $ do > writeIORef wasInCacheRef False > return v > wasInCache <- $ readIORef wasInCacheRef > let recentKeys = nMostRecentKeys capacity S.empty history > QC.assert (S.member k recentKeys == wasInCache) > return ((k, v) : history)

This is our auxiliary function to calculate the N most recent keys, given a recent-first key-value pair list.

> nMostRecentKeys :: Ord k => Int -> S.Set k -> [(k, v)] -> S.Set k > nMostRecentKeys _ keys [] = keys > nMostRecentKeys n keys ((k, _) : history) > | S.size keys >= n = keys > | otherwise = > nMostRecentKeys n (S.insert k keys) history

This test did not cover checking that the values in the cache are correct, but only ensures it retains the correct key-value pairs. This is a conscious decision: I think the retaining/evicting part of the LRU Cache code was the most tricky, so we should prioritize testing that.

Tying everything up

Lastly, we have our tests :: TestTree. It is not much more than an index of tests in the module. We use testCase to pass HUnit tests to the framework, and testProperty for QuickCheck properties.

Note that I usually tend to put these at the top of the module, but here I put it at the bottom of the blogpost for easier reading.

> tests :: TestTree > tests = testGroup "Data.SimpleLruCache" > [ testCase "testCache01" testCache01 > , testCase "testCache02" testCache02 > , testProperty "size == HashPSQ.size" > (sizeMatches :: Cache SmallInt String -> Bool) > , testProperty "priorities < next priority" > (prioritiesSmallerThanNext :: Cache SmallInt String -> Bool) > , testProperty "size < capacity" > (sizeSmallerThanCapacity :: Cache SmallInt String -> Bool) > , testProperty "historic" historic > ]

The last thing we need is a main function for cabal test to invoke. I usually put this in something like tests/Main.hs. If you use the scheme which I described above, this file should look very neat:

module Main where import Test.Tasty (defaultMain, testGroup) import qualified AcmeCompany.AwesomeProduct.Database.Tests import qualified AcmeCompany.AwesomeProduct.Importer.Csv.Tests import qualified AcmeCompany.AwesomeProduct.Importer.Tests import qualified Data.SimpleLruCache.Tests main :: IO () main = defaultMain $ testGroup "Tests" [ AcmeCompany.AwesomeProduct.Database.Tests.tests , AcmeCompany.AwesomeProduct.Importer.Csv.Tests.tests , AcmeCompany.AwesomeProduct.Importer.Tests.tests , Data.SimpleLruCache.Tests.tests ]

If you are still hungry for more Haskell testing, I would recommend looking into Haskell program coverage for mission-critical modules.

Special thanks to Alex Sayers, who beat everyone’s expectations when he managed to stay sober for just long enough to proofread this blogpost.

Categories: Offsite Blogs

Additional functionality using cabal configure flags

haskell-cafe - Thu, 03/12/2015 - 5:39pm
Hi everybody, I am looking for the correct way to provide additional functionality using cabal configure flags. Even though the developer faq [1] says that it is not recommended, I don't see any downsides for an executable package. Is it 'not recommended' even for executable packages? If not, then how can I do it? [1]:
Categories: Offsite Discussion

Learning Haskell - Thu, 03/12/2015 - 4:59pm
Categories: Offsite Blogs

Haskell in Emacs - Thu, 03/12/2015 - 4:24pm
Categories: Offsite Blogs

Haskell in Emacs - Thu, 03/12/2015 - 4:24pm
Categories: Offsite Blogs

Monadic/sequential migration implementation for datain acid-state

haskell-cafe - Thu, 03/12/2015 - 3:28pm
Full description of my problem is on Stack Overflow: Any comments or suggestions would be greatly appreciated! _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe< at >
Categories: Offsite Discussion

Learning Haskell - Thu, 03/12/2015 - 12:49pm
Categories: Offsite Blogs

Bad recursion? When can something be on both sidesof an equation?

haskell-cafe - Thu, 03/12/2015 - 8:49am
Dear Haskellers, In another thread [1], I talked about computing what I've been lately calling the "total descendents" of a subset S of a graph: that is, the set of nodes t for which every maximal sequence of predecessors intersects S. I got it done, functionally [2]. But in the process I wrote something that hangs, and I can't figure out why. The problem arose in the following passage. (Glab stands for Graph Label, a synonym for Int.) totalDescendents :: S.Set Glab -> Graph -> S.Set Glab totalDescendents roots graph = b where (a,b,c,graph) = totalDescendentsCtrlr -- tricky (roots, S.empty, M.empty, graph) totalDescendentsCtrlr :: TotalDescendentsData -> TotalDescendentsData totalDescendentsCtrlr (a,b,c,gr) = if S.null a' -- fails, as does a == a' -- a == a' is one iteration slower but should have same effect then (a',b',c',gr') else totalDescendentsCtrlr (a',b',c',gr') where (a',b',c',gr') = visi
Categories: Offsite Discussion

Theory Lunch (Institute of Cybernetics, Tallinn): Limit languages of cellular automata

Planet Haskell - Thu, 03/12/2015 - 8:32am

At today’s Theory Lunch I discussed limit languages of cellular automata, and Lyman Hurd’s example of a CA whose limit language is not regular. I wrote about this on my other blog.


Categories: Offsite Blogs

TH not compiling when writing the code directly does

haskell-cafe - Thu, 03/12/2015 - 7:07am
I’m stuck getting a TH expansion to compile. When I take the generated code and compile it directly, it is fine. But when expanding and compiling, it fails. The problem seems related to instanceD, where I provide the type as: (appT (appT (conT devName') (varT $ mkName "Word8")) (varT $ mkName "BV”)) which expands to: IDENTIFICATION__MODEL_ID Word8 BV No matter what I put for the second type (BV), it generates the compile error. For example, Word8 or Word16 gives the same error. But if I take the resulting expression and just put it into the file and compile, it compiles fine. So something about expansion is causing the problem. Is there some more correct way to make the expression rather than nesting two appT? Any ideas? Note: the generation of the functions with (map (\f -> returnQ f) (concat funs)) is ugly in my opinion. I could not find the right way to express this. So all ideas welcome. Mike GEN DEC -------------- makeInstance :: String -> [String] -> Q [Dec] makeInstance devName regNam
Categories: Offsite Discussion

David Turner quote on lisp and FP

haskell-cafe - Thu, 03/12/2015 - 5:57am
There is this quote: *It needs to be said very firmly that LISP is not a functional language at all. My suspicion is that the success of Lisp set back the development of a properly functional style of programming by at least ten years.* David Turner found here and there on the net eg Does anyone have/know the original reference? Thanks Rusi
Categories: Offsite Discussion

Mathematical functions with multiple arguments

haskell-cafe - Wed, 03/11/2015 - 10:45pm
Hi everybody, I have a function of type plot :: ([Double] -> Double) -- A function to plot -> [(Double, Double)] -- Range for all arguments -> IO () I want to enforce the fact that ranges for all arguments should be provided. Is there a way to make the type system enforce it?
Categories: Offsite Discussion

References on haskellwiki

haskell-cafe - Wed, 03/11/2015 - 5:21pm
Hi, I've begun to do some formatting on old Monad Readers editions on Haskell Wiki. Unfortunately, there is no support for proper references support. Can the admin add the "Cite" extension ? It would help a lot. Thanks
Categories: Offsite Discussion

Where is Haskell Weekly News syndicated?

haskell-cafe - Wed, 03/11/2015 - 4:25pm
Haskell Weekly News used to be syndicated on and sequence only has HWN up to March 2010, while contemplatecode goes up to the beginning of February. Is there any way that I can subscribe to HWN (preferably as RSS/Atom), and not other stuff that doesn't interest me? -- View this message in context: Sent from the Haskell - Haskell-Cafe mailing list archive at
Categories: Offsite Discussion

Proposal: Export cycleN from Data.Sequence

libraries list - Wed, 03/11/2015 - 4:14pm
Yesterday I rewrote `*>` for Data.Sequence (again), using an internal function cycleN :: Int -> Seq a -> Seq a The name of the function is based on that of Data.Sequence.iterateN. cycleN takes a sequence and cycles it as many times as requested: cycleN 0 $ fromList [1,2] = [] cycleN 5 $ fromList [1,2] = [1,2,1,2,1,2,1,2,1,2] The function is written to maximize sharing in the result sequence and to minimize construction time. Specifically, cycleN n xs should take something like O(|xs| + log n) space (of which all but O(log |xs| + log n) is shared with the structure of xs) and O(log |xs| + log n) time. With current (on GitHub) Data.Sequence exports, the only way to get this functionality with these time and space bounds is to combine replicate with *> : cycleN n xs = replicate n () *> xs This strikes me as a bit unpleasant. David
Categories: Offsite Discussion

-staticlib flag for building standalone static libraries producing very large libraries

glasgow-user - Sat, 03/07/2015 - 1:18pm
Hi all, Can anyone explain the following problem I'm having? I'm currently writing a game in Haskell. When I produce a plain old executable (for local testing) it's about 23M. However, when I create a static lib using the -staticlib flag it is 54M. Why the discrepancy? Sean _______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users< at >
Categories: Offsite Discussion

New gtk2hs 0.12.4 release

gtk2hs - Wed, 11/21/2012 - 12:56pm

Thanks to John Lato and Duncan Coutts for the latest bugfix release! The latest packages should be buildable on GHC 7.6, and the cairo package should behave a bit nicer in ghci on Windows. Thanks to all!


Categories: Incoming News