Flygdynamikern

2014-09-12

At last week's CUFP I did a talk called “Haskell tools for satellite operations”. The abstract is:

Since 2013-04 the presenter has been supporting SSC (the Swedish Space Corporation) in operating the telecommunications satellite “Sirius 3” from its Mission Control Center in Kiruna. Functions in the satellite vendor's operations software are breaking down as the orbit of the ageing satellite degrades. To fill in the gaps in software capabilities the presenter has developed several operational tools using Haskell.

The talk will give an overview of the satellite operations environment, the tools developed in Haskell, how they benefitted (and occasionally suffered) from the choice of implementation language, which (public) libraries were critical to their success, and how they were deployed in the satellite operations environment.

A video recording of the talk is available on the CUFP page for the talk and on youtube.

2014-02-11

My numtype and numtype-tf libraries both needed one line changes to be compatible with the GHC 7.8.1 release candidate. Versions 1.1 and 0.1.2 (respectively) have been uploaded to hackage.

The update to numtype also necessitated an update to dimensional, mainly to bump the upper bounds of the numtype dependency, but a few API additions snuck in too. The change log for the new version (0.12.3), as well as the other versions that have been uploaded to hackage since my previous version announcement can be found at the bottom of this post.

Dimensional-tf didn’t need an update for GHC 7.8 but has been updated with the same API additions as dimensional.

I skipped the experimental and to my knowledge unused CGS and Extensible modules. If you would like to see them ported let me know.

For straight-forward usage, e.g. the examples on the dimensional wiki, the only change required from library users to switch from dimensional to dimensional-tf is inserting .TF in the import statements. E.g.:

Compiler errors will also be different in dimensional-tf, for better or for worse.

So, should you use dimensional or dimensional-tf? For the time being I consider dimensional-tf to be experimental. If you want stability stick with dimensional for now. If your dislike of functional dependencies trumps your need for stability, then try dimensional-tf. If dimensional-tf eventually proves itself to be a better dimensional I will merge it into the latter with a major version bump.

I’ve implemented the numtype-tf library which is in essence numtype using type families (hence the “-tf”) instead of functional dependencies. Some of my design decisions are slightly different (beside the choice of type system extension), e.g. the representation of negative integers is different and the PosType and NegType classes have been dropped in numtype-tf. The haddocks have also been improved a little.

A feature of the functionally dependent numtype that I was unable to reproduce with type families is ”mutual dependencies”, used in the Sum and Div type classes of numtype. Here is an example of type signatures (instances omitted) and ghci usage:

In order for the latter to compute we must assist the type checker by being explicit about the type of a0, i.e. pos3 - pos5 :: Neg2, which largely defeats the purpose of type level arithmetic. Instead two type families are used in numtype-tf:

This works OK but the lack och mutual dependencies in type families restricts what I will losely refer to as “type inference back tracking”. This may or may not be a significant drawback compared to fundep numtype depending on the use case.

If you are interested in comparing code written with type families to code written with functional dependencies take a look at the respective modules on Github: Numeric.NumType.TF vs. Numeric.NumType.

The next step is to reimplement dimensional as dimensional-tf in order to exercise numtype-tf and better understand the impact of the differences with respect to numtype. I am also looking forward to playing with GHC.TypeNats in GHC 7.4.

2011-09-15

I posted the following example of an internationalized form to the Yesod Cookbook a few days ago. Yesod has a pretty awesome library for programming with forms and also a flexible but currently under-documented system for internationalization. However, how the two interact, while straightforward, might not be immediately obvious to the newcomer. Hence the motivation for the below example which shows how to internationalize both custom messages and Yesod's built-in FormMessages (mostly form error messages).

2011-06-17

Herein we will create a rudimentary unsafe URL shortener – a toy. We will see how to use David Himmelstrup’s acid-state to persist a data structure and how to use Michael Snoyman’s Yesod to build a simple web application.

This URL shortener is unsafe not in the sense of unsafePerformIO or unsafeCoerce, but in the sense that it is wide open to abuse. If you use it as anything other than a toy The Internet (spammers et al) will have you for breakfast. Jason Jacek has written a good article on the good and bad of URL shorteners; if you are looking for a non-toy URL shortener use one of the products he recommends.

This post is literate Haskell; just copy and paste it into a .lhs file and build/run with GHC.

Preliminaries

Language extensions, imports, and all that. There’s just no way around them!

State

We first create an appropriate (for some definition of appropriate) data structure for storing URLs. Then we will give that data structure ACID (Atomicity, Consistency, Isolation and Durability) guarantees by way of the acid-state package.

URL storage data structure

We’re going to keep things real simple and stuff our URLs into an IntMap using sequentially increasing keys. We also keep track of the latest key assigned.

> dataURLStore=URLStoreKey (IntMapURL)

Now we create the API we will use for our URL store. We need to be able to create an empty store, add URLs, and retrieve the URL corresponding to a given key.

Finally, let some magic happen and, ta-da, we have our ACIDic URL store! In particular this creates Add and Retrieve data constructors that will be used below as proxies for add and retrieve.

> $(makeAcidic ''URLStore ['add, 'retrieve])

The Yesod web app

All that is missing now is the web app that will use our ACIDic state. We’ll use Yesod to for that but only scratch the surface of all the good stuff Yesod can do (including persistence).

Seth Falcon has written a survey of URL shortening service APIs. Our API will is very basic: POST a href parameter to / to get a short URL (a GET will also do the job, I’ll let convenience trump idempotency here).

First we define the Yesod foundation type URLShort and make it an instance of Yesod. The foundation will have to carry its state.

The return () at the end is there to help GHC infer a suitable type of getRedirectR.

Applicationification (main)

Our main runs the yesod application with its AcidState. The port number to run on must be provided. Bad arguments crash (I already mentioned that this is a toy, right?). A bracket ensures that the AcidState is checkpointed and closed on exit.