News aggregator

Douglas M. Auclair (geophf): March 2016 1HaskellADay Problems and Solutions

Planet Haskell - Thu, 03/31/2016 - 12:54pm

Categories: Offsite Blogs

cabal: --enable-tests by default

haskell-cafe - Thu, 03/31/2016 - 3:11am
In the future, could cabal --enable-tests by default when `cabal install`ing local project directories? Other languages' package managers automatically do this, a more intuitive default behavior.
Categories: Offsite Discussion

Testing Msgpack system

haskell-cafe - Thu, 03/31/2016 - 12:41am
Dear friends, we have a distributed system written in Haskell, consisting of three types of nodes with dozen of instances of each of two types and a central node of the third type. Each node is started by executing a binary which sets up acid-state persistence layer and sockets over which msgpack messages are sent around. It is trivial to write low level functionality quickcheck test suites, which test properties of functions. We would like, however, to have a quickcheck-esque suite which sets up the network, then gets it to an arbitrary valid state (sending correct messages between nodes), then rigorously testing it for three high-level properties: 1. Chaos monkey test (disable random node, see if certain invariants hold); 2. Evil node test (make several nodes work against the system, see if certain properties hold); 3. Rigorous testing of network-wide invariants, if all the nodes operate correctly. The problem we're facing is the following — if we want to inspect state of nodes in Haskell-land, we
Categories: Offsite Discussion

Melbourne Haskell Users Group Meetup, Tonight,31-03-2016 < at > 6:30pm

haskell-cafe - Wed, 03/30/2016 - 11:00pm
Hi All, Tonight we're having our monthly Haskell meetup in the Melbourne CBD. Please come along if you're interested and free! Hope to see you there :) Regards, - Lyndon _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe< at >
Categories: Offsite Discussion

Functional Jobs: Haskell Developer - Remote at Stack Builders (Full-time)

Planet Haskell - Wed, 03/30/2016 - 6:03pm

About Us

Stack Builders is a software consultancy dedicated to going beyond delivering great products for clients - we want to change the software industry through the use of better tools and practices.

Stack Builders has offices in New York City and Quito, Ecuador. We are looking for a remote Haskell Developer to help us solve complex and exciting challenges on our projects. Approximately 25% of our development is currently in Haskell and Clojure with that percentage continually growing.

About You

Stack Builders is searching for a seasoned specialist in Haskell development to join our growing, global team. We would like to welcome someone to our team who has 3+ years of experience and enjoys working on diverse projects with a mix of local and remote teams.

Requirements & Responsibilities:

  • CS degree
  • Ability to maintain normal working hours close to Eastern Standard Time
  • 3+ years of experience
  • High level of oral, technical, and written communication skills
  • Ability to critically think and offer solutions to clients
  • Ability and interest in teaching others on the team, setting priorities for projects and making sure they are completed
  • Strong understanding of pure functional programming and functional programming concepts such as algebraic data types, folds, polymorphism, and recursion
  • Strong understanding of concepts such as monoids, functors, applicative functors, and monads
  • Experience with building projects and package management using Cabal and/or Stack
  • Experience with unit testing (hspec) and property-based testing (QuickCheck)
  • Experience with basic libraries such as base, bytestring, containers, mtl, text, transformers, etc.
  • Experience with server side programming using frameworks such as Snap or Yesod (or Servant)
  • Experience with database libraries (esqueleto, mysql-simple, persistent, postgresql-simple, etc.), encoding/decoding libraries (aeson, cassava, yaml, etc.), parsing libraries (attoparsec, megaparsec, parsec, etc.)

Some of our perks:

  • Constant professional development, weekly R&D meetings
  • Strong culture of learning and professional development
  • Chance to visit our South American offices

To apply:

Please send your resume to careers [at] stackbuilders [dot] com and include a link to a GitHub profile.

Get information on how to apply for this position.

Categories: Offsite Blogs

parsec reorganization

haskell-cafe - Wed, 03/30/2016 - 2:30pm
Ive been trying parsec And I gather that the modules structures are heavily reorganized eg starts with import Data.Char (char) which immediately gives Module ‘Data.Char’ does not export ‘char’ Change that to import Text.Parsec.Char (char) and that error goes and more and more arcane ones start Likewise all the stuff here seems to be wrong paths Is there no tutorial for the current versions? ghc 7.8.4 parsec 3.1.9-2 _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe< at >
Categories: Offsite Discussion

Brent Yorgey: CIS 194 materials now on github

Planet Haskell - Tue, 03/29/2016 - 3:45pm

I’ve been meaning for a while to put the source files for my CIS 194 materials in a publically accessible place, and I’ve finally gotten around to it: you can now find everything in byorgey/haskell-course on github.

I make no particular guarantees about anything; e.g. there is a crufty, complicated shake script that builds everything, but it probably doesn’t even compile with the latest version of Shake.

There are some obvious next steps, for which I have not the time:

  1. Get everything building again
  2. Fix any outstanding typos, confusions, etc.
  3. Update it to be more specifically for general-audience learning rather than for a course at Penn
  4. Find a permanent web home for the material. It’s sort of a happy accident that it has been accessible on the Penn site for so long, but it’s not a stable situation; I don’t even know who would have access to that site anymore.

All the material is licensed under a Creative Commons Attribution 4.0 International License, so go wild using it however you like, or working on the above next steps. Pull requests are very welcome, and I will likely give out commit access like candy.

Categories: Offsite Blogs

Type equality with "forall"

haskell-cafe - Tue, 03/29/2016 - 2:17pm
There are no problems in the code you have posted so far: it works exactly as it is supposed to. Overlapping instances worked as designed. It seems the problem is not in Haskell but in your expectations of existentials. Existentials are a means of abstraction, that is, deliberately forgetting details. In our case, forgetting all the details about the type. Consider the following code data W where Wrap :: a -> W test1 = case Wrap True of Wrap x -> not x It does not type-check. The variable x in test1 has the type which is different from any other existing type. Therefore, you cannot do anything sensible with it -- in particular, you cannot apply 'not', which works only for Booleans. Can't GHC just see that ``x is Bool''
Categories: Offsite Discussion

Functional Jobs: Functional Programmer at Rakuten Inc. (Full-time)

Planet Haskell - Tue, 03/29/2016 - 9:37am

Rakuten Inc.'s Ichiba is one of the biggest internet market places in the world. We have been experiencing rapid growth since we opened in 1997. A new team is being built up to create innovative tools and services to support internal business users and contribute to continuous growth. Rakuten is well known as the company in Japan where English is the lingua franca.

Our tech stack currently includes the following (in no particular order):

  • Scala
  • Scalaz
  • Finagle
  • Thrift
  • MongoDB
  • Splunk
  • Ansible
Job Description
  • Invent, design and implement new services and tools supporting internal business users
  • Communicate clearly within the team but also across the organisation
  • Help managing the teams own backlog and roadmap
Required skills and behaviour
  • Critical thinking even under time pressure
  • Never tired to stop learning and help others do the same
  • Having a "pull" attitude to both work and knowledge
  • Be a nice person that works well within a diverse team
  • TOEIC 800
Experience with any type of the following a plus
  • Analytics, data-warehousing and business intelligence
  • Information visualisation
  • Some knowledge of Japanese
  • Previous experience with Scala, Haskell or any other typed functional programming language
  • Apache Mesos and/or Aurora
  • Enjoying green-tea

Some travel (to HQ or to branch offices) will be required.

Get information on how to apply for this position.

Categories: Offsite Blogs

Munich Haskell Meeting, 2015-03-30 < at > 19:30

haskell-cafe - Mon, 03/28/2016 - 10:55pm
Dear all, This week, our monthly Munich Haskell Meeting will take place again on Wednesday, March 30 at Cafe Puck at 19h30. For details see here: If you plan to join, please add yourself to this dudle so we can reserve enough seats! It is OK to add yourself to the dudle anonymously or pseudonymously. Everybody is welcome!
Categories: Offsite Discussion

Hspec + QuickCheck passing type

haskell-cafe - Mon, 03/28/2016 - 6:53pm
Hi, I'm writing the following Hspec + QuickCheck test for some type: context "Type1" $ it "decode inverses encode" $ property $ \x -> (decode . encode) x == Right (x::Type1) However, I have a number of these types, and I could write the same test for every type, but that isn't very DRY. Therefore I would like to put the test in a function and call that function for every type. Something like the following: typeTest name = do context name $ it "decode inverses encode" $ property $ \x -> (decode . encode) x == Right x Unfortunately this doesn't work, since QuickCheck doesn't know which Arbitrary instance to use. How can I pass the type, e.g. x::Type1, to this function so QuickCheck knows what Arbitrary instance to use? Kind regards, Martijn Rijkeboer
Categories: Offsite Discussion

[2nd CFP] Haskell Symposium 2016

General haskell list - Mon, 03/28/2016 - 6:44pm
======================================================================== ACM SIGPLAN CALL FOR SUBMISSIONS Haskell Symposium 2016 Nara, Japan, 22-23 September 2015, directly after ICFP ======================================================================== ** The Haskell Symposium has an early track this year ** ** See the Submission Timetable for details. ** The ACM SIGPLAN Haskell Symposium 2016 will be co-located with the International Conference on Functional Programming (ICFP 2016) in Vancouver, Canada. The Haskell Symposium aims to present original research on Haskell, discuss practical experience and future development of the language, and to promote other forms of denotative programming. Topics of interest include: * Language Design, with a focus on possible extensions and modifications of Haskell as well as critical discussions of the
Categories: Incoming News

[2nd CFP] Haskell Symposium 2016

haskell-cafe - Mon, 03/28/2016 - 6:44pm
======================================================================== ACM SIGPLAN CALL FOR SUBMISSIONS Haskell Symposium 2016 Nara, Japan, 22-23 September 2015, directly after ICFP ======================================================================== ** The Haskell Symposium has an early track this year ** ** See the Submission Timetable for details. ** The ACM SIGPLAN Haskell Symposium 2016 will be co-located with the International Conference on Functional Programming (ICFP 2016) in Vancouver, Canada. The Haskell Symposium aims to present original research on Haskell, discuss practical experience and future development of the language, and to promote other forms of denotative programming. Topics of interest include: * Language Design, with a focus on possible extensions and modifications of Haskell as well as critical discussions of the
Categories: Offsite Discussion

Joey Hess: type safe multi-OS Propellor

Planet Haskell - Mon, 03/28/2016 - 5:29am

Propellor was recently ported to FreeBSD, by Evan Cofsky. This new feature led me down a two week long rabbit hole to make it type safe. In particular, Propellor needed to be taught that some properties work on Debian, others on FreeBSD, and others on both.

The user shouldn't need to worry about making a mistake like this; the type checker should tell them they're asking for something that can't fly.

-- Is this a Debian or a FreeBSD host? I can't remember, let's use both package managers! host "" $ props & aptUpgraded & pkgUpgraded

As of propellor 3.0.0 (in git now; to be released soon), the type checker will catch such mistakes.

Also, it's really easy to combine two OS-specific properties into a property that supports both OS's:

upgraded = aptUpgraded `pickOS` pkgUpgraded type level lists and functions

The magick making this work is type-level lists. A property has a metatypes list as part of its type. (So called because it's additional types describing the type, and I couldn't find a better name.) This list can contain one or more OS's targeted by the property:

aptUpgraded :: Property (MetaTypes '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish ]) pkgUpgraded :: Property (MetaTypes '[ 'Targeting 'OSFreeBSD ])

In Haskell type-level lists and other DataKinds are indicated by the ' if you have not seen that before. There are some convenience aliases and type operators, which let the same types be expressed more cleanly:

aptUpgraded :: Property (Debian + Buntish) pkgUpgraded :: Property FreeBSD

Whenever two properties are combined, their metatypes are combined using a type-level function. Combining aptUpgraded and pkgUpgraded will yield a metatypes that targets no OS's, since they have none in common. So will fail to type check.

My implementation of the metatypes lists is hundreds of lines of code, consisting entirely of types and type families. It includes a basic implementation of singletons, and is portable back to ghc 7.6 to support Debian stable. While it takes some contortions to support such an old version of ghc, it's pretty awesome that the ghc in Debian stable supports this stuff.

extending beyond targeted OS's

Before this change, Propellor's Property type had already been slightly refined, tagging them with HasInfo or NoInfo, as described in making propellor safer with GADTs and type families. I needed to keep that HasInfo in the type of properties.

But, it seemed unnecessary verbose to have types like Property NoInfo Debian. Especially if I want to add even more information to Property types later. Property NoInfo Debian NoPortsOpen would be a real mouthful to need to write for every property.

Luckily I now have this handy type-level list. So, I can shove more types into it, so Property (HasInfo + Debian) is used where necessary, and Property Debian can be used everywhere else.

Since I can add more types to the type-level list, without affecting other properties, I expect to be able to implement type-level port conflict detection next. Should be fairly easy to do without changing the API except for properties that use ports.


As shown here, pickOS makes a property that decides which of two properties to use based on the host's OS.

aptUpgraded :: Property DebianLike aptUpgraded = property "apt upgraded" (apt "upgrade" `requires` apt "update") pkgUpgraded :: Property FreeBSD pkgUpgraded = property "pkg upgraded" (pkg "upgrade") upgraded :: Property UnixLike upgraded = (aptUpgraded `pickOS` pkgUpgraded) `describe` "OS upgraded"

Any number of OS's can be chained this way, to build a property that is super-portable out of simple little non-portable properties. This is a sweet combinator!

Singletons are types that are inhabited by a single value. This lets the value be inferred from the type, which came in handy in building the pickOS property combinator.

Its implementation needs to be able to look at each of the properties at runtime, to compare the OS's they target with the actial OS of the host. That's done by stashing a target list value inside a property. The target list value is inferred from the type of the property, thanks to singletons, and so does not need to be passed in to property. That saves keyboard time and avoids mistakes.

is it worth it?

It's important to consider whether more complicated types are a net benefit. Of course, opinions vary widely on that question in general! But let's consider it in light of my main goals for Propellor:

  1. Help save the user from pushing a broken configuration to their machines at a time when they're down in the trenches dealing with some urgent problem at 3 am.
  2. Advance the state of the art in configuration management by taking advantage of the state of the art in strongly typed haskell.

This change definitely meets both criteria. But there is a tradeoff; it got a little bit harder to write new propellor properties. Not only do new properties need to have their type set to target appropriate systems, but the more polymorphic code is, the more likely the type checker can't figure out all the types without some help.

A simple example of this problem is as follows.

foo :: Property UnixLike foo = p `requires` bar where p = property "foo" $ do ...

The type checker will complain that "The type variable ‘metatypes1’ is ambiguous". Problem is that it can't infer the type of p because many different types could be combined with the bar property and all would yield a Property UnixLike. The solution is simply to add a type signature like p :: Property UnixLike

Since this only affects creating new properties, and not combining existing properties (which have known types), it seems like a reasonable tradeoff.

things to improve later

There are a few warts that I'm willing to live with for now...

Currently, Property (HasInfo + Debian) is different than Property (Debian + HasInfo), but they should really be considered to be the same type. That is, I need type-level sets, not lists. While there's a type level sets library for hackage, it still seems to require a specific order of the set items when writing down a type signature.

Also, using ensureProperty, which runs one property inside the action of another property, got complicated by the need to pass it a type witness.

foo = Property Debian foo = property' $ \witness -> do ensureProperty witness (aptInstall "foo")

That witness is used to type check that the inner property targets every OS that the outer property targets. I think it might be possible to store the witness in the monad, and have ensureProperty read it, but it might complicate the type of the monad too much, since it would have to be parameterized on the type of the witness.

Oh no, I mentioned monads. While type level lists and type functions and generally bending the type checker to my will is all well and good, I know most readers stop reading at "monad". So, I'll stop writing. ;)


Thanks to David Miani who answered my first tentative question with a big hunk of example code that got me on the right track.

Also to many other people who answered increasingly esoteric Haskell type system questions.

Also thanks to the Shuttleworth foundation, which funded this work by way of a Flash Grant.

Categories: Offsite Blogs

Kevin Reid (kpreid): Representing the radio spectrum as spatial audio

Planet Haskell - Sun, 03/27/2016 - 8:17pm

In software-defined radio, there are well-established ways of visually representing the signal(s) in the entire bandwidth available from the hardware; we create a plot where the horizontal axis is frequency (using the Fourier transform to obtain the data). Then either the vertical axis is amplitude (creating an ordinary graph, sometimes called panorama) or the vertical axis is time and color is amplitude (creating a waterfall plot).

Here is an example of ShinySDR's spectrum display which includes both types (y=amplitude above and y=time below):

A further refinement is to display in the graph not just the most recent data but average or overlay many. In the above image, the blue fill color in the upper section is an overlay (both color and height correspond to amplitude), the green line is the average, and the red line is the peak amplitude over the same time interval.

We can see signals across an immensely wide spectrum (subject to hardware limitations), but is there a way to hear them meaningfully? Yes, there is, with caveats.

What's pictured above is a small portion of the band assigned to aviation use — they are used primarily for communication between aircraft in flight and air traffic control ground stations. The most significant thing about these communications is that there are a lot of different frequencies for different purposes, so if you're trying to hear “what's in the area”, you have to monitor all of them.

The conventional solution to this problem is a scanner, which is a radio receiver programmed to rapidly step through a range of frequencies and stop if a signal is detected. Scanners have disadvantages: they will miss the beginning of a signal, and they require a threshold set to trade off between missing weak signals and false-triggering on noise.

An alternative, specific to AM modulation (which is used by aircraft), is to make a receiver with very poor selectivity: the ability to receive only a specific channel and ignore other signals. (Historically, when RF electronic design was less well understood and components had worse characteristics, selectivity was a specification one would care about, but only if one lived in an area with closely-spaced radio stations — today, every receiver has good selectivity.)

I'm going to explain how to build an unselective receiver in software, and then refine this to create spatial audio — that is, the frequency of the signal shall correspond to the stereo panning of the output audio. This is the analogue of the spectrum display in audio.

Of course, this is an AM receiver and so it will only make intelligible sound for amplitude-modulated signals. However, many signals will produce some sound in an AM receiver. The exception is that a clean frequency-modulated (FM) or phase-modulated signal will produce silence, because its amplitude is theoretically constant, but this silence is still audibly distinct from background noise (if the signal is intermittent), and transmitted signals often do not have perfect constant amplitude.


A normal software AM demodulator has a structure like the following block diagram (some irrelevant details omitted). The RF signal is low-pass filtered to select the desired signal, then demodulated by taking the magnitude (which produces an audio signal with a DC offset corresponding to the carrier).

In order to produce an unselective receiver, we omit the RF filter step, and therefore also the downsampling — therefore demodulating at the RF sample rate. The resulting real signal must be low-pass filtered and downsampled to produce a usable audio sample rate (and because the high-frequency content is not interesting; see below), so we have now “just” swapped the two main components of the receiver.

This simple change works quite well. Two or more simultaneous AM signals can be received with clear stereo separation.

One interesting outcome is that, unlike the normal AM receiver, the audio noise when there is no signal is quieter (assuming AGC is present before the demodulator block in both cases) — this conveniently means that no squelch function is needed.

The reason for this is obvious-in-hindsight: loosely speaking, most of the noise power will be at RF frequencies and outside of the audio passband. In order to have a strong output signal, the input signal must contain a significant amount of power in a narrow band to serve as the AM carrier and sideband. (I haven't put any math to this theory, so it could be nonsense.)

Adding stereo

In order to produce the spatial audio, we want the audio signal amplitude, in a single stereo channel, to vary with frequency. And that is simply a filter with a sawtooth frequency response. The signal path is split for the two stereo channels, with opposite-slope filters. (AGC must be applied before the split.)

An undesired effect is that near the band edges, since the filter has a steep but not perfectly sharp transition from full-left to full-right, there is a lot of slope detection (output from frequency-modulated signals) that does not occur anywhere else. Of course,

This design can of course be applied to more than two audio channels; using surround sound would avoid the need for steepness of the filter at the edges and map the inherently circular digitized spectrum to a circular space, so it's worth trying.


I've implemented this in ShinySDR (and it is perhaps the first novel DSP feature I've put in). Just click the “AM unselective” mode button.

Some “directions for future research”:

As I mentioned above, this is useless for listening to FM signals. Is some technique which can do the same for FM? Naïvely creating an “unselective FM receiver” seems like it would be a recipe for horrible noise, because to a FM demodulator, noise looks like a very loud signal (because the apparent frequency is jumping randomly within the band, and frequency maps to amplitude of the output).

If we declare that the output need not be intelligible at all, is there a way to make a receiver that will respond to localized signal power independent of modulation? Can we make an unmodulated carrier act like an AM signal? (CW receivers do this using the BFO but that is dependent on input frequency.)

Categories: Offsite Blogs

Christopher Allen: Speeding up the automated building and testing of our Haskell projects

Planet Haskell - Sun, 03/27/2016 - 6:00pm

Alternate title: Arrest me for crimes against GNU Make.

I work for a company that uses Haskell for its primary application. We’re quite fond of having automatic builds fired off for each push to a branch and in our Github pull requests, so we were using CircleCI for our builds. Our circle.yml looked a bit like this initially:

machine: ruby: version: 2.1.7 services: - postgresql node: version: 5.1.0 dependencies: pre: - sudo apt-key adv --keyserver --recv-keys 575159689BEFB442 - echo 'deb trusty main' | sudo tee /etc/apt/sources.list.d/fpco.list - sudo apt-get update && sudo apt-get install stack -y - cd frontend && npm install - cd frontend && ./node_modules/.bin/bower install - npm install -g purescript - gem install bundler --pre - cd sql && bundle install override: - stack setup - cd app && make frontend: timeout: 3000 environment: UV_THREADPOOL_SIZE: 2 - make dirty: pwd: app test: override: - make sql - make -C sql migrate - stack test --jobs=1

However, I’m also a bit of a speed demon and impatient, so I was getting tired of the slow builds we had with CircleCI. 25-30 minutes for each build is just way too long when you’re waiting for the green checkmark to review code or merge it. My first pass was attempting to figure out what could be parallelized and what could be cached. Here’s what we added under dependencies for caching:

cache_directories: - "~/.stack" - ".stack-work" - "frontend/node_modules" - "frontend/bower_components" - "frontend/output"

But it wasn’t good enough.

Even with caching, our CircleCI builds were taking about 20 minutes.

We got a dedicated server and put on it instead of using CircleCI. We couldn’t have afforded the enterprise version of CircleCI and using something we can modify ourselves had a lot of appeal. Drone uses Docker to manage the build environment and after getting our build working and tests passing inside of the Docker containers, I was able to get Drone tracking our Github stuff pretty quickly. This got us down to about 6 minutes in order to do the following:

  1. Build frontend assets
  2. Build two different Haskell projects and run their respective tests

Here’s approximately what the .drone.yml looked like:

build: image: app environment: - POSTGRES_PORT_5432_TCP_ADDR=localhost commands: - make tests notify: slack: webhook_url: OUR_WEBHOOK_URL channel: dev username: drone template: > build #{{ build.number }} finished with a {{ build.status }} status. Commit message: {{build.message}} - See more at {{system.link_url}}/{{repo.owner}}/{{}}/{{build.number}} compose: db: image: postgres environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=password app: image: app environment: - POSTGRES_PORT_5432_TCP_ADDR=localhost depends_on: - db

Note that we used Drone’s baked in Docker Compose’ish functionality so that we didn’t have to also configure a PostgreSQL server in the same container. make tests ends up running:

make -C sql/ test make -C lib/ test make -C app/ test

These tasks stood up and migrated the database, built our business logic library and ran the tests, and build our web app and ran the tests.

I wasn’t satisfied though, so I realized that since Drone uses Docker containers and our Haskell projects use Stackage LTS for our package versions, all we needed to do was specify our current LTS resolver and build a bunch of dependencies we knew we’d need. Here’s what I added to the Docker build container’s Dockerfile in order to pre-build the dependencies:

# Setup Stack RUN stack setup --resolver lts-5.8 # ADD global-stack.yaml ~/.stack/global-project/stack.yaml # RUN stack setup --resolver lts-5.8 # Cache some deps RUN stack --resolver lts-5.8 build lens-aeson yesod yesod-test esqueleto http-client free classy-prelude-yesod classy-prelude-conduit case-insensitive gravatar wreq xml-conduit warp hspec QuickCheck wai-logger persistent-postgresql HUnit uuid-aeson monad-logger mandrill email-validate yesod-auth yesod-newsfeed yesod-form haskell-src-exts cpphs polyparse xml-hamlet th-orphans either base-compat th-expand-syns th-lift MonadRandom

The fruit of my effort was:

Screenshot of a recent build & test run taking only 2 minutes or so. I elided the branch name.

In so doing, our build times dropped from 20 or 25 minutes with CircleCI, down to 2-3 minutes on our private Drone server.

Here’s the steps we took:

  1. Added caching to our CircleCI build. This got us: 25 minutes -> 20 minutes.

  2. Switched from CircleCI on their shared servers to Drone on a $100/month dedicated server. This got us: 20 minutes -> 6 minutes.

  3. Started pre-building dependencies. This got us: 6 minutes -> 2 or 3 minutes.

Note that these 2 or 3 minutes isn’t just building a Haskell project, that takes a couple seconds. About half the time is spent building frontend assets! Our test suite is relatively fast because we cache things like the Yesod application initialization. I believe we could get this down to a minute or two, but I don’t want to muck about with our PureScript build chain. Even with two Haskell developers, we think the $100/month and time to get it working paid off quickly.

I would estimate Drone took slightly longer than CircleCI originally did to get working initially, but I think the small difference is worth it and that it would’ve been faster for someone that dislikes Docker less.

I know this site is a bit of a disaster zone, but if you like my writing or think you could learn something useful from me, please take a look at the book I've been writing with my coauthor Julie. There's a free sample available too!

Posted on March 28, 2016

Categories: Offsite Blogs

HGamer3D has a new dependency installer

haskell-cafe - Sat, 03/26/2016 - 8:56pm
Dear All, it took a long while, but now a new solution has been found for dependency setup for HGamer3D. What do you think? Check here: . regards uotbw _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe< at >
Categories: Offsite Discussion

build error using hsqml

haskell-cafe - Sat, 03/26/2016 - 7:15pm
Hello, I'm trying to build a program using HsQml. cabal 1.14.0 fails with this error: Building HsQmlTest-0.0.1... Preprocessing executable 'HsQmlTest' for HsQmlTest-0.0.1... [1 of 1] Compiling Main ( src/Main.hs, dist/build/HsQmlTest/HsQmlTest-tmp/Main.o ) Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Loading package array- ... linking ... done. Loading package deepseq- ... linking ... done. Loading package containers- ... linking ... done. Loading package filepath- ... linking ... done. Loading package tagged- ... linking ... done. Loading package bytestring- ... linking ... done. Loading package text- ... linking ... done. Loading package transformers- ... linking ... done. <command line>: can't load .so/.DLL for: /home/fabien/.cabal/lib/hsqml- ( cannot open shared object file: No
Categories: Offsite Discussion

[ANN] Csound-expression-5 is out (framework forcomputer music)

haskell-cafe - Sat, 03/26/2016 - 6:47pm
I'd like to announce a new version of Csound-expression library. It's a framework for computer music production. It compiles Haskell code to Csound. What's new? **The 5.0 is out! New features:** csound-expression * **Microtonal tunings**. We can use custom temperaments with insturments, patches, soundfonts and MIDI-instruments. Check out the guide on tuning and microtonal music (see also module `Csound.Tuning`). There are many predefined tunings (including ancient ones). Now we can play the authentic Bach music with Haskell! See [Custom temperament. Microtonal music]( ) for details. * **Functions for Csound API**. We can interface with generated code through many other languages. We can generate the code with Haskell and the use it in other environments. we can build UI with Python or Clojure, we can create an Android synthesizer. See the guide section on Csound API. See [Csound API. Using ge
Categories: Offsite Discussion

Sponsored: The 3 Week Diet - Fri, 03/25/2016 - 2:00am
8 Rules of Fat Loss. Warning: Fast Results! Click Here to Watch Video...
Categories: Offsite Blogs