Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
Haskell hacking
[go: Go Back, main page]


Haskell Hacking: a journal of Haskell programming



2006-09-27

Love of Diagrams

Listening to the new Love of Diagrams self-titled EP. I'd caught them opening for Sonic Youth back in July, and they just blew me away -- the energy, the swirling noise and angular sounds, so I was looking forward to this release. And now they've signed to Matador (home of Interpol), so hopefully there's a full album around the corner.

/home :: /music :: permalink :: rss

2006-09-23

Mirror of Simple Unix Tools for Haskell

Unfortunately a power failure has meant that haskell.org is down. So here's a mirror of yesterday's 'unix tools tutorial'.

The mirror.

/home :: /haskell :: permalink :: rss

2006-09-22

Haskell for Unix

Today a small tutorial for beginner Haskell programmers, wondering what to do with the language. We implement a range of common unix tools as Haskell one liners, using a "just show me the code" philosophy. The examples should help give a flavour of the beauty and expressiveness of Haskell programming. Here's a preview of complete programs:

-- The 'cat' program
cat     = input id

-- Sort a file
srt     = input sort

-- Reverse a file (tac)
tac     = input reverse

-- remove duplicate lines from a file (like uniq)
uniq    = input nub

Read the tutorial.

/home :: /haskell :: permalink :: rss

2006-09-21

A 5 minute introduction to testing Haskell with QuickCheck

Following an interesting query on the haskell-cafe mailing list, I've put up a very quick introduction to testing Haskell code using the QuickCheck testing framework.

The tutorial.

/home :: /haskell :: permalink :: rss

2006-09-20

Efficient wiki editing with W3M and Vim

I find I spend quite some time editing wiki pages, such as the Haskell.org wiki. However, browser-based editing leaves a lot to be desired, generally making the editing process more inefficient and difficult than it needs to be. I suspect that these inefficiencies hamper contributions, especially in longer texts. The main problem with wiki editing is the browser-based editor forms aren't proper editors, so you're just wasting your time using them.

Key missing features are:
  • Syntax highlighting
  • Regular expressions substitutions
  • Spell checking
  • Programming tool support (particular for a PL wiki like Haskell.org)

We can fill these holes, and improve efficiency, by using the text-based browser w3m along with your favourite text editor, which for me is Vim. w3m is a simple, fast, terminal browser, which uses an external editor by default, for editing online forms.

Syntax highlighting for wiki files, with embedded Haskell, and Vim is available here. Save this to your ~/.vim/syntax directory, and enable it dynamically when editing online with :setf haskellwiki.

Using your favourite editor from w3m is as simple as setting: editor: vim -c "setf haskellwiki" in the w3m configuration screen (type o in w3m to bring this up). This also enables syntax highlighting by default, including Haskell fragments embedded in "<haskell>" tags.

And of course, vim being vim, you have access to unix tools via the shell (such as aspell), programming tools like lambdabot (pointfree refactoring of wiki code, anyone?) and more.

More details on text editor support for wiki editing, from a variety of browsers. Thanks to jgrimes for advice on this.

Finally, for the future, I'd like to investigate a generic mechanism for exporting wiki pages to a local revision control system, such as darcs. For large wiki subsections I work on, I currently save files locally in a new darcs repository, edit them, then upload the subsection in a single pass when complete. This is tedious -- power users should always have a revision control back end to the wiki, for pushing and pulling changes directly. This is the way this blog is published: developed in a local darcs repository, and then pushed to a public repository, which blosxom then renders. Ideally, preparing wiki articles too should involve only the editor and a revision control system, for publishing.

/home :: /net :: permalink :: rss

2006-09-11

Persistent irc declarations, at last

One of the more oft-requested lambdabot features finally got implemented today: persistent value bindings. So lambdabot behaves more like a communal Haskell session. Let's define a useful combinator:
lambdabot> let eq f g = \x -> f x == g (x::[Int])
Defined.
Which we can refer to as a local binding:
lambdabot> > L.eq head last [1..10]
 False
Or pass to QuickCheck:
lambdabot> check head `L.eq` last
 Exception: Prelude.head: empty list
Telling us our property isn't quite right. Let's fix that:
lambdabot> let eqnotnull f g = \x -> (not (null x)) ==> f x == g (x::[Int])
Defined.
Which is much more useful:
lambdabot> check head `L.eqnotnull` last
 Falsifiable, after 0 tests: [2,0]
Or even something True:
lambdabot> check minimum `L.eqnotnull` (head . sort)
 OK, passed 500 tests.
I like having the machine figure stuff like this out for me.

/home :: /haskell :: permalink :: rss

2006-09-10

Syntax highlighting for the planet

planet.haskell.org now supports syntax highlighting of Haskell code using Malcolm Wallace's HsColour tool. To colorise your Haskell fragments, build and install HsColour, and run it with -css. The following source:
-- main :: IO ()
main = print $ case Just e of
        Nothing -> error "no return"
        Just x  -> x
    where e = map (+1) [1..100]
Handed to HsColour, and then prune the head and body tags, leaving a css-ified pre markup:
$ HsColour -css A.hs | sed '1,/body/d;s,</body>,,;$d'

-- main :: IO ()
main = print $ case Just e of
        Nothing -> error "no return"
        Just x  -> x
    where e = map (+1) [1..100]
Which uses the css tags defined here. Happy typesetting!

/home :: /haskell :: permalink :: rss

QuickCheck for the IRC masses

Lambdabot's plugin list keeps growing. We now have a QuickCheck plugin. QuickCheck is a rather spiffy unit test generator/framework, used particuarly for checking invariants in Haskell libraries. The lambdabot plugin makes it available from irc or the command line, to check properties of Haskell code. Ok, something basic:
lambdabot> check True
 OK, passed 100 tests.

A bit more complex:

lambdabot> check False == True
 Falsifiable, after 0 tests:

A list property:

lambdabot> check \s -> (reverse . reverse) s == id (s :: [Int])
 OK, passed 100 tests.

Or for partial functions:

lambdabot> check \s -> (head . sort) s == minimum (s :: [Int])
 Exception: Prelude.head: empty list

Ah, so better specify the precondition:

lambdabot> check \s -> not (null s) ==> (head . sort) s == minimum (s :: [Int])
 OK, passed 100 tests.

Or an invalid property:

lambdabot> check \s -> not (null s) ==> (head . sort) s == maximum (s :: [Int])
 Falsifiable, after 2 tests:
    [1,0]

We can hook this into the free theorem's plugins, just for fun:

lambdabot> free filter
$map f . filter (g . f) = filter g . $map f

lambdabot> check \f g s -> (map (f::Int->Int) . filter (g . f)) s ==
                           (filter g . map f) (s::T)
OK, passed 100 tests.

And we're already using it to answer language questions! Live from #haskell:

16:46  glguy:: ?type rem
16:46  lambdabot:: forall a. (Integral a) => a -> a -> a
16:46  glguy:: ?type mod
16:46  lambdabot:: forall a. (Integral a) => a -> a -> a
16:46  glguy:: synonyms?
16:51  dons:: ?check \a b -> a `rem` b == a `mod` (b :: Int)
16:51  lambdabot::  Exception: divide by zero
16:51  glguy:: heh
16:51  dons:: ?check \a b -> b > 0 ==> a `rem` b == a `mod` (b :: Int)
16:51  lambdabot::  Falsifiable, after 8 tests:
16:51  lambdabot:: -3
16:51  glguy:: ohhh negative numbers
16:51  dolio:: Ah, there you go. Dividing by negatives is different.
16:51  dons:: ?check \a b -> (a > 0 && b > 0) ==> a `rem` b == a `mod` (b :: Int)
16:52  lambdabot::  OK, passed 100 tests.
16:52  dons:: ?check \a b -> (a < 0 && b > 0) ==> a `rem` b == a `mod` (b :: Int)
16:52  lambdabot::  Falsifiable, after 6 tests:
16:52  lambdabot:: -2
16:52  dons:: QuickCheck++

/home :: /haskell :: permalink :: rss

2006-09-09

More free theorems for lambdabot

Hot on the tail of Andrew Bromage's free theorems plugin for Lambdabot, we now have two free theorem generators, thanks to Janis Voigtlaender and Sascha Boehme's FT tool.

lambdabot> ft map
 forall T1,T2 in TYPES. forall h1 :: T1 -> T2, h1 strict.
  forall T3,T4 in TYPES. forall h2 :: T3 -> T4, h2 strict.
   forall f1 :: T1 -> T3.
    forall g1 :: T2 -> T4.
     (forall x2 :: T1.
      h2 (f1 x2) = g1 (h1 x2))
     ==> forall x1 :: [T1].
        map h2 (t1 f1 x1) = t1 g1 (map h1 x1)

lambdabot> ft foldl1
 forall T1,T2 in TYPES. forall h1 :: T1 -> T2, h1 strict.
  forall f1 :: T1 -> T1 -> T1.
   forall g1 :: T2 -> T2 -> T2.
    (forall x2 :: T1.
     forall x3 :: T1.
      h1 (f1 x2 x3) = g1 (h1 x2) (h1 x3))
    ==> forall x1 :: [T1].
       h1 (t1 f1 x1) = t1 g1 (map h1 x1)

/home :: /haskell :: permalink :: rss

2006-09-04

Rewriting Haskell Strings

Yay. All done! The new paper describing the stream fusion system used in Data.ByteString is finished. Check it out :)

/home :: /haskell :: permalink :: rss

About

Real World Haskell

RWH Book Cover

Archives

Recommended

Blog Roll

Syndicate