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-08-28

More stream fusion

Some benchmarks for the Data.ByteString unstable branch, implementing the new stream fusion system to remove intermediate arrays. GHC does a really good job generating array traversal code using streams. Here's the difference between fps 0.7 and the unstable branch, for a range of fusible array functions:
Yay for rewrite rules! Here's a comparison of the strict and lazy ByteString types, indicating the complexity difference for lazy functions that manipulate on the spine of the lazy ByteString:

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

2006-08-26

Theorems for free and undoing monads in lambdabot

Two new fun plugins for lambdabot this week. The first, by Andrew Bromage, is @free, a free theorems generator. Given a function's type, the plugin returns theorems that hold for that function:

lambdabot> free sortBy :: (a -> a -> Ordering) -> [a] -> [a]
g x y = h (f x) (f y) => map f . sortBy g = sortBy h . map f

lambdabot> free foldl :: (a -> b -> a) -> a -> [b] -> a
f . h x = k (f x) . g => f . foldl h y = foldl k (f y) . map g

lambdabot> free filter :: (a -> Bool) -> [a] -> [a]
g x = h (f x) => map f . filter g = filter h . map f

lambdabot> free fmap :: (a -> b) -> F a -> F b
g . h = k . f => $map_F g . fmap h = fmap k . $map_F f

lambdabot> free sequence_ :: [M a] -> M ()
g y = y => mapM g (sequence_ x) = sequence_ (map (mapM f) x)

lambdabot> free unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
 (((
    g (fst y) = fst z && f (snd y) = snd z
  ) =>
    p y = z
  ) =>
    mapMaybe p (h x) = k (f x)
  ) =>
    map g . unfoldr h = unfoldr k . f

Cool, huh? Free properties for your code! (Lots of properties checkable with QuickCheck perhaps..)

The second new plugin, written by Spencer Janssen, is @undo, a desugarer for do-notation, meaning we can plug monadic syntax into other lambdabot plugins:

lambdabot> undo do x <- f ; y <- g ; return (mapM_ k $ x ++ y)
f >>= \ x -> g >>= \ y -> return (mapM_ k $ x ++ y)

which we can then feed to the pointfree plugin:

lambdabot> compose pl undo do x <- f ; y <- g ; return (mapM_ k $ x ++ y)
(`fmap` g) . (mapM_ k .) . (++) =<< f

or find the type of:

lambdabot> compose type compose pl undo \f g k -> do x <- f ; y <- g ; return (mapM_ k $ x ++ y)
 forall a (m :: * -> *) b (m1 :: * -> *).
        (Monad m, Monad m1) =>
            m1 [a] -> m1 [a] -> (a -> m b) -> m1 (m ())

Haskell is fun!

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

What mp3 players should be like

My new M-Cody M20 mp3 player arrived today from the UK. Mmm... design.
MCody M20

Its tiny, smaller than a nano ipod, and when idle is completely black -- the OLED screen disappears. 2G is plenty, and it also has an FM tuner with presets, as well as a text file viewer.

The sound is great (after ditching the headphones it came with, and plugging in some good Sennheiser ones). The touch sensitive case took an hour or so to really get the handle of, and it seems quite intuitive now.

Had a bit of trouble at the start using it under OpenBSD (I managed to mangle the partition table on the device, and couldn't produce a vfat fs anyway), but under Linux things work perfectly, appearing like a usb stick.

So, all in all: tiny, beautiful, functional.

/home :: /hardware :: permalink :: rss

Haskell on 32 processors and beyond

Roman Leshchinskiy mentioned yesterday that he managed to get GHC running SMP Data Parallel Haskell on a 32 cpu Sun E6900, with memory, 80G real and 500G swap (a bargain at somewhere around $250,000 US for this midrange server)

Its fun watching GHC Haskell scale so well..

An aside: DPH uses stream fusion to automatically fuse concurrent array code. In Data.ByteString we adapted the rewrite rules and code, to instead fuse code over flat, unboxed Word8 arrays, for fast strings.

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

2006-08-07

more default defaults

In normal Haskell you can use what is possibly the most obscure Haskell98 feature, the default keyword, to modify how type defaulting works, and resolve ambiguities -- but only for numeric classes. The result is less type signatures, as below:
default(Double)

main = print $ 2 + 1
In ghci, this defaulting has been extended to the Eq, Ord and Show classes, so we can write, in ghci:
> reverse []
[]
and ghci will find the right Show instance. Now, in lambdabot, we can evaluate user's code in the irc channel, but often the user has to add extra types to have the right Show instance found:
dons:: > reverse []
lambdabot:: Add a type signature
dons:: > reverse [] :: [()]
lambdabot:: []
This is annoying. What would be really nice is if the defaulting mechanism used by ghci was available to userland Haskell, by a -fglasgow-extension of the default keyword mechanism.

Update Simon has now kindly added a new flag to GHC, "-fextended-default-rules", which does exactly this. Lambdabot won't be second class anymore :)

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

2006-08-04

Stream fusion

Duncan Coutts and I have been furiously hacking away at a new array fusion system for Data.ByteString, using an improved set of loop combinators based on hylomorphisms. Some initial results (raw) are available.
  • Old system, which people are now using.
  • New system, based on stream fusion, using latest ghc patches, which we hope to have out in the next couple of weeks.
int-e on #haskell kindly graphed the results. For fuseable pipelines, this gives some indication of the speed ups people are likely to see in ghc 6.6. The numbers compare fuseable functions that traverse the byte strings in various directions, with and without accumulators. And once again QuickCheck has been hugely helpful in getting our rewrite rules correct, and spotting flaws in our reasoning. GHC seems to do a much better job generating tight, strict loop with the new combinators :)

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

2006-08-03

main :: IO a

Noticed today that in the ghc 6.5 branch, the following program is valid:
main :: IO String
main = return "hello, world"
This works for any return type, in Show, it seems. (Except, notably, ()).
$ runhaskell A.hs 
"hello, world"

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

About

Real World Haskell

RWH Book Cover

Archives

Recommended

Blog Roll

Syndicate