Archive for the ‘Haskell’ Category

Parameterised monads

Sunday, February 15th, 2009

This post assumes some knowledge of Haskell, in particular what monads and monad transformers are. It's literate Haskell, which means you can load it into ghci directly (well, you'll probably have to convert HTML entities to plain text first, particularly > and <.)

> {-# LANGUAGE NoImplicitPrelude, MultiParamTypeClasses, FunctionalDependencies #-}
> {-# LANGUAGE FlexibleInstances, FlexibleContexts, UndecidableInstances #-}
> 
> import Prelude hiding (Monad (..))
> import qualified Prelude as P
> import Control.Monad.Trans

On the Haskell blog circuit recently the notion of "parameterised monad" has been floating about, provoked by a new paper "Parameterized Notions of Computation". I'll refrain from explaining it myself, instead linking to Dan Piponi's post on the topic. If you don't already know what parameterised monads are, go and read that.

It seems that a module has already been written to encode parameterised modules and uploaded to Hackage: Control.Monad.Parameterized (package monad-param). It dates from before the current excitement (2007 and it's at version 0.0.2) so the concept is apparently not new. It does however take a somewhat different approach, one that's seemingly more general but also more cumbersome. The change in approach is explained in a blog post by its author, Edward Kmett. Here's what the "parameterized monad" class would look like if translated from the paper:

(more...)

How to cheat at Mensa puzzles

Saturday, February 9th, 2008

At freshers’ fayre (yeah, a long time ago now) I was handed a slip from Mensa. I intended to follow it up later but being busy I never got round to it. Today I rediscovered it on my desk, and of course it had a couple of puzzles on it. One is a pretty simple number sequence. The other has you find an anagram:

Rearrange the letters of ‘ANY TIME‘ to give a seven letter word. What is it?

Obviously “anytime” is excluded (well, we’re not Americans ;). I tried to find one manually for a while, but then realised I could just solve it with a couple of commands:

[pwb@rhuidean ~]$ ghci -e 'Monad.mapM_ putStrLn (let s = "anytime" in filter (\s2 -> all (`elem` s2) s) $ Control.Monad.replicateM 7 s)' > words
[pwb@rhuidean ~]$ grep -f words /usr/share/dict/words

This was taking a long time. But then I realised you can cut out a big chunk of the search space by filtering out all the non-anagrams, which you can do easily with grep.

[pwb@rhuidean ~]$ grep '^[anytime]{7}$' /usr/share/dict/words | grep -f words
amenity
anytime

I wonder how this reflects on my intelligence… :)

QOTD XIV

Monday, July 30th, 2007

From the outside, the type systems of languages like Haskell and ML tend to look like a sort of archaic ecstatic religious rite. The bleeding mendicants pause as they shuffle past, sing a verse in praise of the purifying pain of strong typing, then prod themselves with pointy sticks and progress along their lonely road.

Bryan O’Sullivan, commenting on his own quotation of Yaron Minsky. I’ve heard people complain about Haskell’s type system as being too strict, but once you figure out how to get things to type check, you can actually use it like a miniature theorem prover. Which is, essentially, what it is.

Oh yeah, and it’s my birthday today.

More from the list monad

Wednesday, July 18th, 2007
Prelude Control.Monad> let truthPermutations n = replicateM n [False,True]
Prelude Control.Monad> truthPermutations 3
[[False,False,False],[False,False,True],[False,True,False],[False,True,True],
[True,False,False],[True,False,True],[True,True,False],[True,True,True]]
Prelude Control.Monad> let satisfies p [x,y,z] = p x y == z
Prelude Control.Monad> filter (satisfies (==>)) $ truthPermutations 3
[[False,False,True],[False,True,True],[True,False,False],[True,True,True]]

Try expressing truth tables so succinctly and at such a high level in an imperative language. The list monad rocks.

Codata

Monday, July 16th, 2007

On Planet Haskell today, sigfpe posted a fairly readable (i.e., hopefully comprehensible to non-experts) essay about Data and Codata. I intend to do a talk on this topic someday, but in the meantime, you might find this enlightening.

One-line definition of the power set function

Monday, July 2nd, 2007

If you thought the one-line definition of the Fibonacci sequence in Haskell was beautiful, try this:


import Control.Monad
powerset :: [a] -> [[a]]
powerset = filterM (const [True, False])

A black box for sure, unless you have “internalized the list monad“. But it does show how stonkingly powerful monads are.

Unix pipelines vs. lazy evaluation

Sunday, June 3rd, 2007

(In response to Gimbo.)

Speaking of Unix, I have thought that there is a pretty close connection between lazy evaluation and Unix pipelines. On the xmonad home page there’s an example for using dzen that looks like this:


while true ; do
    date +"%H.%M %a %b %d"
    sleep 60
done | dzen2 -ta r -fg ’#a8a3f7’ -bg ’#3f3c6d’


Of course, if that was strictly/eagerly evaluated, dzen would never run, because of the infinite loop. But what actually happens is that the two commands, joined together by a pipe (indicated by the | character), are executed in parallel; the while loop runs date, producing some output, which it writes to a pipe (just a first-in-first-out buffer shared by the two processes); it sleeps for 60 seconds; then it runs date again; sleeps again; …, ad infinitum. Meanwhile, dzen reads its output, until there is none left, then blocks until the loop provides more.

(more…)

Type inference rocks

Monday, May 28th, 2007

I just wrote the following snippet of code for my dissertation:


intNatI :: Int :~= Nat
intNatI = Iso {
            to   = fromInteger . toInteger,
            from = fromInteger . toInteger }

The components to and from have totally different types (to is Int -> Nat, from is Nat -> Int). Yay for type inference! :)

Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo

Thursday, May 10th, 2007

The title of this entry (if you take “buffalo” to be 1) the obvious noun with identical plural, 2) capitalised, the proper noun referring to the American city, and 3) a verb meaning approximately “bully”) is a grammatically correct sentence of English. (I first came across it in The Language Instinct by Stephen Pinker, but was reminded of it recently.)

In fact, according to Wikipedia, for any n ≥ 1, buffalon is a grammatically correct sentence, if you disregard capitalisation. (“Buffalo!”, “Buffalo buffalo”, “Buffalo buffalo buffalo”, etc.)

Don’t you just love natural language?

QOTD VIII

Wednesday, February 7th, 2007


Quoth Doaitse Swierstra, nevermore,
>  digest.chew.eat.serve.cook.chop.pluck.kill $ chicken
>
> we all have a definite feeling that after applying the functions, the
> original object is no longer available, and the FP view does not feel
> entirely natural.

Yes, that is true. I can sort of see why people might object to the IO
monad in this case, since it explicitly prevents the programmer from
reusing old data. Of course, one might argue that it's not really the
*monad* that prevents it, but the construction of the physical world.
The monad merely prevents us from trying to eat our cake and have it.


Dougal Stanton on haskell-cafe (archive).


For the uninitiated, the dots refer to function composition; in OO notation it would look like chicken.kill().pluck().chop().cook().serve().eat().chew().digest(). The point is that that kind of composition in Haskell implies there are no side effects. Consider:


let chicken = getChicken
in  (chicken,
    (digest.chew.eat.serve.cook.chop.pluck.kill) chicken)

Here we’ve taken a chicken, eaten it, and returned the result along with the original chicken — i.e, we eat our chicken and have it. This is what the IO monad stops you from doing, and why composing functions that perform side effects is difficult.


This is perhaps a good introduction to a rather interesting video I also saw linked from haskell-cafe (in fact in the same thread). It’s only available in WMV unfortunately (it does come from MS after all).