Re: strict Haskell dialect

2006-02-04 Thread Tomasz Zielonka
On Thu, Feb 02, 2006 at 11:46:56PM +0100, Wolfgang Jeltsch wrote:
 Am Mittwoch, 1. Februar 2006 11:49 schrieb Bulat Ziganshin:
  [...]
 
  i had one idea, what is somewhat corresponding to his discussion:
 
  make a strict Haskell dialect. implement it by translating all
  expressions of form f x into f $! x and then going to the standard
  (lazy) haskell translator. the same for data fields - add to all field
  definitions ! in translation process. then add to this strict
  Haskell language ability to _explicitly_ specify lazy fields and lazy
  evaluation, for example using this ~ sign
 
  what it will give? ability to use Haskell as powerful strict language,
  what is especially interesting for real-world programmers. i have
  found myself permanently fighting against the lazyness once i starting to
  optimize my programs. for the newcomers, it just will reduce learning
  path - they don't need to know anything about lazyness
 
 Since laziness often allows you to solve problems so elegantly, I'm really 
 scared of the idea of a Strict Haskell! :-(  Is laziness really so unreal 
 that real-world programmers have to see it as an enemy which they have to 
 fight against?
 
 In fact, I was kind of shocked as I read in Simon Peyton Jones' presentation 
 Wearing the hair shirt [1] that in his opinion Lazyness doesn't really 
 matter.

I am with you. If Haskell switches to strictness, I am going to stay
with the old compilers, I guess... I just love laziness (or
non-strictness).  Maybe speculative evaluation is the way to go?

Best regards
Tomasz

-- 
I am searching for programmers who are good at least in
(Haskell || ML)  (Linux || FreeBSD || math)
for work in Warsaw, Poland
___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://haskell.org/mailman/listinfo/haskell-prime


Re: strict Haskell dialect

2006-02-04 Thread Ben Rudiak-Gould

Chris Kuklewicz wrote:

Weak uses seq to achieve WHNF for it's argument


newtype Weak a = WeakCon {runWeak :: a}
mkWeak x = seq x (WeakCon x)
unsafeMkWeak x = WeakCon x


This doesn't actually do what you think it does. mkWeak and unsafeMkWeak are 
the same function.


mkWeak 123 = seq 123 (WeakCon 123) = WeakCon 123
unsafeMkWeak 123 = WeakCon 123
mkWeak _|_ = seq _|_ (WeakCon _|_) = _|_
unsafeMkWeak _|_ = WeakCon _|_ = _|_

To quote John Meacham:

| A quick note,
| x `seq` x
| is always exactly equivalant to x. the reason being that your seq
| would never be called to force x unless x was needed anyway.
|
| I only mention it because for some reason this realization did not hit
| me for a long time and once it did a zen-like understanding of seq
| (relative to the random placement and guessing method I had used
| previously) suddenly was bestowed upon me.

I remember this anecdote because when I first read it, a zen-like 
understanding of seq suddenly was bestowed upon /me/. Maybe it should be in 
the docs. :-)


-- Ben

___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://haskell.org/mailman/listinfo/haskell-prime


Parallel list comprehensions

2006-02-04 Thread John Hughes

I noticed ticket #55--add parallel list comprehensions--which according to
the ticket, will probably be adopted. I would argue against.

Firstly: because in its more general forms the notation is confusing. Try
this example:

[(i,j,k) | i-[1..3], j-[1..3] | k - [1..9]]

In general it's hard to predict how the elements from each set of 
generators

and filters will match up.

Secondly: because the notation lacks expressive power. When I use zip in a
comprehension, it's often in a definition like this one:

positions x xs = [i | (i,x') - zip [0..] xs, x==x']

I'm zipping the two lists together *so that I can relate the two* in a
subsequent filter. The parallel comprehension notation cannot express this.
(You can certainly write

wrong_positions x xs = [i | i - [0..] | x' - xs, x==x']

but it does the wrong thing).

Thirdly: because even in situations where it can be applied, the gain is
small. Using zip explicitly is almost equally concise, and (thanks to being
explicit) more readable and understandable.

My opinion may be coloured by the fact that I never use the things. 
However,

I think it's a mistake to add rarely used features with a small payoff to
the language. It just makes the language larger, harder to learn, and 
harder

to read for all but the expert, without much corresponding benefit.

John

___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://haskell.org/mailman/listinfo/haskell-prime


Re[2]: Priorities

2006-02-04 Thread Bulat Ziganshin
Hello John,

Friday, February 03, 2006, 8:11:48 PM, you wrote:

 Yes.  Plus, I'd say, the presence of threading primitives that return
 certain well-defined exceptions or something along those lines, so that
 it's not necessary to know whether multithreading is supported at
 compile time.

JM Also, I can't think of any reason you would ever want to defer such a
JM decision to run time. either your program needs concurrency and thus
JM should fail at compile time if it isn't available or it just needs to be
JM concurrent-safe in which case it will succeed and work portably because
JM we have included the primitives needed to allow that.

GHC's libs (including handling of Handles) check threaded at
run-time just to have one common compiled library instead of two ones

-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]



___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://haskell.org/mailman/listinfo/haskell-prime


Re[2]: give equal rights to types and classes! :)

2006-02-04 Thread Bulat Ziganshin
Hello Marcin,

Saturday, February 04, 2006, 2:23:50 AM, you wrote:
 if my idea was incorporated in Haskell, this change don't require
 even changing signatures of most functions working with arrays -
 just Array type become Array interface, what a much difference?

What would 'Eq - Eq - Ord - Bool' mean?
MQK '(Eq a, Eq b, Ord c) = a - b - c - Bool'?
MQK   '(Eq a, Ord b) = a - a - b - Bool'?
MQK   '(Eq a, Ord a) = a - a - a - Bool'?

as i stated in the post, the one class name instantiates one variable.
so the proper variant will be second

i know that this syntax can't substitute ALL possible uses of
preconsitions, it's just for most common, in my sense. moreover, it
will help to convert currently used types to classes, and to easily
refactor user programs back and forth between using types and classes


-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]



___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://haskell.org/mailman/listinfo/haskell-prime


Re[3]: give equal rights to types and classes! :)

2006-02-04 Thread Bulat Ziganshin
Hello Dave,

Saturday, February 04, 2006, 3:52:46 AM, you wrote:
 Now i'm trying to generalize my functions parameters/results to type
 classes instead of single types. for example, getFileSize function can
 return any numeric value, be it Integer, Word or Int64. This,
 naturally, results in those long and awkward signatures. Allowing to
 write type of result as just Integral makes signature smaller
 and more understandable for me:
 
 getFileSize :: Stream Monad h - Monad Integral

DM How does that type translate back into current Haskell? Assuming
DM Stream is a type, and not a class, I see at least three possibilities:

DM (Integral a, Monad m) = Stream m h - m a
DM (Integral a, Monad m1, Monad m2) = Stream m1 h - m2 a
DM (Integral a, Monad m) = (forall m. Monad m = Stream m h) - m a

first and i said that in my post. the translation includes only moving
classes to the left side of = and types to the right side of =,
and using one type variable per each class name. btw, Stream is a
class in my lib, so the right translation is:

(Integral int, Monad m, Stream m h) = h - m int


-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]



___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://haskell.org/mailman/listinfo/haskell-prime


Re[2]: strict Haskell dialect

2006-02-04 Thread Bulat Ziganshin
Hello Tomasz,

Saturday, February 04, 2006, 12:39:38 PM, you wrote:

  make a strict Haskell dialect.

TZ I am with you. If Haskell switches to strictness,

as i said, strict _dialect_ is interesting for optimization, moving
from other languages and making strict variants of data structures

-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]



___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://haskell.org/mailman/listinfo/haskell-prime


Re: Parallel list comprehensions

2006-02-04 Thread Duncan Coutts
On Sat, 2006-02-04 at 15:11 +0100, John Hughes wrote:
 I noticed ticket #55--add parallel list comprehensions--which according to
 the ticket, will probably be adopted. I would argue against.

Can I second this?

The only time I ever used a parallel list comprehension was by accident.
I accidentally used '|' rather than ',' in a list comprehension and
ended up with a bug that was quite hard to track down.

Now one could argue that I could make a similar mistake with pretty much
any language feature, but it's precisely because it's a rarely used
language feature that it makes this problem worse because you're not
looking for that kind of problem.

Duncan

___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://haskell.org/mailman/listinfo/haskell-prime


Re: FilePath as ADT

2006-02-04 Thread Marcin 'Qrczak' Kowalczyk
Axel Simon [EMAIL PROTECTED] writes:

 The solution of representing a file name abstractly is also used by
 the Java libraries.

I think it is not. Besides using Java UTF-16 strings for filenames,
there is the File class, but it also uses Java strings. The
documentation of listFiles() says that each resulting File is made
using the File(File, String) constructor. The GNU Java implementation
uses a single Java string inside it.

On Windows the OS uses UTF-16 strings natively rather than byte
sequences. UTF-16 and Unicode is almost interconvertible (modulo
illegal sequences of surrogates), while converting between UTF-16
and byte sequences is messy. This means that unconditionally using
Word8 as the representation of filenames would be bad.

I don't know a good solution.

  *   *   *

Encouraged by Mono, for my language Kogut I adopted a hack that
Unicode people hate: the possibility to use a modified UTF-8 variant
where byte sequences which are illegal in UTF-8 are decoded into
U+ followed by another character. This encoding is used as the
default encoding instead of the true UTF-8 if the locale says that
UTF-8 should be used and a particular environment variable is set
(KO_UTF8_ESCAPED_BYTES=1).

The encoding has the following properties:

- Any byte sequence is decodable to a character sequence, which
  encodes back to the original byte sequence.

- Different character sequences encode to different byte sequences
  (the U+ escape is valid only when it would be necessary).

- It coincides with UTF-8 for valid UTF-8 byte sequences not
  containing 0x00, and character sequences not containing U+.

It's a hack, and doesn't address other encodings than UTF-8, but it
was good enough for me; it allows to maintain the illusion that OS
strings are character strings. Alternatives were:

* Use byte strings and character strings in different places,
  sometimes using a different type depending on the OS (Windows
  filenames would be character strings).

  Disadvantages: It's hard to write a filename to a text file.
  The API is more complex. The programmer must too often care
  about the kind of a string.

* Fail when encountering byte strings which can't be decoded.

-- 
   __( Marcin Kowalczyk
   \__/   [EMAIL PROTECTED]
^^ http://qrnik.knm.org.pl/~qrczak/
___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://haskell.org/mailman/listinfo/haskell-prime


Re: objective data on use of extensions

2006-02-04 Thread Ian Lynagh
On Fri, Feb 03, 2006 at 11:38:09AM -0800, Isaac Jones wrote:
 I would like to strive to find objective data on the use of
 extensions.  I started a table here which summarizes how popular
 extensions are in real-life code.  We need more data points, though.
 
 http://hackage.haskell.org/trac/haskell-prime/wiki/ExtensionsExperiment
 
 I have a short program which queries the hackage database, gets some
 details about all of the packages there, and summarizes them into a
 table.

I'm not sure how useful this info is, as:

* You won't get, for example, FunctionalDependencies from any libraries
  or applications that make use of Control.Monad.State.

* Many extensions turn into -fglasgow-exts/-98, so if I use
  functional dependencies and rank 2 types but only declare
  FunctionalDependencies and not Rank2Types then nothing is going to
  tell me I've made a mistake. (I think it would be great if this was
  fixed). (Ideally something could warn about unused extensions too, but
  that's trickier).

* People will sometimes be willing to jump through hoops to avoid using
  an unportable extension.


That said, FWIW, I have the following in my cabalised libraries (none in
hackage AFAIK):

* ForeignFunctionInterface, TemplateHaskell, TypeSynonymInstances
* TypeSynonymInstances
* ForeignFunctionInterface
* ForeignFunctionInterface
* EmptyDataDecls, CPP
* EmptyDataDecls, ForeignFunctionInterface

Thanks
Ian

___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://haskell.org/mailman/listinfo/haskell-prime


Re: Parallel list comprehensions

2006-02-04 Thread Andres Loeh
 I noticed ticket #55--add parallel list comprehensions--which according to
 the ticket, will probably be adopted. I would argue against.

[Several good points removed.]

I agree.

Cheers,
  Andres
___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://haskell.org/mailman/listinfo/haskell-prime


Re: Parallel list comprehensions

2006-02-04 Thread Jon Fairbairn
On 2006-02-04 at 15:11+0100 John Hughes wrote:
 I noticed ticket #55--add parallel list comprehensions--which according to
 the ticket, will probably be adopted. I would argue against.

I also agree. 

 Firstly: because in its more general forms the notation is confusing. Try
 this example:
 
  [(i,j,k) | i-[1..3], j-[1..3] | k - [1..9]]
 
 In general it's hard to predict how the elements from each
 set of generators and filters will match up.

and I always think it's going to do something cooler -- a
fair list product (like , only working on infinite lists),
not a zip, and then I'm disappointed when I remember it
doesn't. So it just uses up some syntax (ie adds possible
errors) without adding anything really useful.

There ought to be a list_product somewhere (I mean [1..]
`list_product` [4..] ==
[(1,4),(2,4),(1,5),(3,4),(2,5),(1,6),...]). Is there?

 Jón

-- 
Jón Fairbairn  Jon.Fairbairn at cl.cam.ac.uk


___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://haskell.org/mailman/listinfo/haskell-prime


Re: Parallel list comprehensions

2006-02-04 Thread Jan-Willem Maessen


On Feb 4, 2006, at 9:11 AM, John Hughes wrote:

I noticed ticket #55--add parallel list comprehensions--which  
according to

the ticket, will probably be adopted. I would argue against.
...


I tend to agree.  But to back myself up, I thought I'd do an informal  
survey of uses of zip or zipWith in comprehensions.  I did this  
using grep -C 5 and hand inspection, so tallys may be off by 1 or  
2.  I counted three things:
  1) Uses of zip and friends which could be replaced by zip  
comprehensions, but which weren't simply numbering the elements of a  
list (OK)
  2) Uses of the list numbering idiom zip [n..] (...) and zip  
(...) [n...] (Number)
  3) Uses of zip and friends which are not list numbering, and  
cannot be replaced by zip comprehensions. (Not OK)


Conclusion: Haskell would benefit from a library function for the  
list-numbering idiom.  (Plus, such a library would play nicely with  
any evaluation strategy you care to name...)  This would eliminate  
more than half the uses of zip in comprehension generators.


I was surprised to see that phc would have been the biggest  
beneficiary of zip comprehensions!


-Jan-Willem Maessen


OK = Could use zip comprehensions.
Number = zip [n..] (...) or zip (...) [n..]
Not OK = Can't use zip comprehensions---prior or subsequent clauses

OK  Number  Not OK
phc  6   1   5
Djinn4
DrIFT4
fps  1
GHC 11  15  12
happy   11
HSlibs/  2   8
libraries

Total   19  44  17

___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://haskell.org/mailman/listinfo/haskell-prime


Re: Parallel list comprehensions

2006-02-04 Thread Stefan Holdermans

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

I noticed ticket #55--add parallel list comprehensions--which  
according to

the ticket, will probably be adopted. I would argue against.


[...]

For what's it worth: I totally agree with John. Not only does this  
seems to me like a feature that'll be so little used to justify the  
introduction of special syntax, I also it'll make the language far  
less accessible for newbies.


Just my $ .02,

  Stefan
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.1 (Darwin)

iD8DBQFD5PybX0lh0JDNIpwRAvq6AKCo0iB5GQioWEvAdeJEp2V2ZHvZgwCdEnv6
U4X5NgQzv7bAHZdqcHUd5dE=
=IjMp
-END PGP SIGNATURE-
___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://haskell.org/mailman/listinfo/haskell-prime


Re: Priorities

2006-02-04 Thread John Meacham
On Sat, Feb 04, 2006 at 01:40:26PM +0300, Bulat Ziganshin wrote:
 GHC's libs (including handling of Handles) check threaded at
 run-time just to have one common compiled library instead of two ones

Yeah, but I don't expect a common compiled library between
different implementations.
John

-- 
John Meacham - ⑆repetae.net⑆john⑈
___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://haskell.org/mailman/listinfo/haskell-prime


Re: Parallel list comprehensions

2006-02-04 Thread Jan-Willem Maessen


On Feb 4, 2006, at 1:31 PM, Jon Fairbairn wrote:

...
There ought to be a list_product somewhere (I mean [1..]
`list_product` [4..] ==
[(1,4),(2,4),(1,5),(3,4),(2,5),(1,6),...]). Is there?


Not that I know of, but here's one which handles finite lists  
correctly; it'd be a nice addition to Data.List:


dzip :: [a] - [b] - [(a,b)]
dzip =  dzipWith (,)

dzipWith :: (a - b - c) - [a] - [b] - [c]
dzipWith f [] ys = []
dzipWith f as [] = []
dzipWith f as (y:ys) = dzipK ys [y]
  where dzipK (b:bs) rbs =
zipWith f as rbs ++ dzipK bs (b : rbs)
dzipK [] rbs = dzipT as
  where dzipT ys@(_:yt) = zipWith f ys rbs ++ dzipT yt
dzipT [] = []

-Jan-Willem Maessen



 Jón

--
Jón Fairbairn  Jon.Fairbairn at  
cl.cam.ac.uk



___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://haskell.org/mailman/listinfo/haskell-prime


___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://haskell.org/mailman/listinfo/haskell-prime


Re: [Haskell-cafe] Re[2]: strict Haskell dialect

2006-02-04 Thread Jan-Willem Maessen


On Feb 3, 2006, at 8:16 PM, Brian Hulley wrote:


Jan-Willem Maessen wrote:


I pointed out some problems with strict Haskell in a recent talk, but
I think it'd be worth underscoring them here in this forum.


Is the text of this talk or points raised in it available online  
anywhere?


snip There is one very difficult piece of syntax in a strict  
setting: The

*where* clause.  The problem is that it's natural to write a bunch of
bindings in a where clause which only scope over a few conditional
clauses.  I'm talking about stuff like this:

f x
  | p x   = . a ...a . a  a ...
  | complex_condition = . b .. b ... b ..
  | otherwise = . a ... b .
  where a = horrible expression in x which is bottom when
complex_condition is true.
b = nasty expression in x which doesn't terminate when p x
is true.
complex_condition = big expression which
 goes on for lines and lines
 and would drive the reader
 insane if it occurred in line.


Surely it would not be too difficult for the compiler to only  
evaluate the where bindings that are relevant depending on which  
guard evaluates to True ie in your example, the binding for a would  
be evaluated if p x is True, otherwise the complex_condition would  
be evaluated, and if True, b would be evaluated, otherwise a and b  
would be evaluated: ...


In principle, yes, this is eminently doable.  But the translation  
becomes surprisingly messy when the bindings in question are mutually  
recursive.  Certainly it's not a simple syntax-directed translation,  
in contrast to essentially every other piece of syntactic sugar in  
the language.


-Jan-Willem Maessen

___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://haskell.org/mailman/listinfo/haskell-prime


Re: Parallel list comprehensions

2006-02-04 Thread Andrew Pimlott
On Sat, Feb 04, 2006 at 06:31:56PM +, Jon Fairbairn wrote:
 There ought to be a list_product somewhere (I mean [1..]
 `list_product` [4..] ==
 [(1,4),(2,4),(1,5),(3,4),(2,5),(1,6),...]). Is there?

This is called fair conjunction in Backtracking, Interleaving, and
Terminating Monad Transformers [1].

(-) :: [a] - (a - [b]) - [b]
[] - f = []
(x:xs) - f = interleave (f x) (xs - f)

interleave :: [a] - [a] - [a]
interleave [] ys = ys
interleave (x:xs) ys = x : interleave ys xs

t = take 6 ([1..] - \x - 
[4..] - \y - 
[(x, y)])

Andrew

[1] http://okmij.org/ftp/Computation/monads.html#LogicT
___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://haskell.org/mailman/listinfo/haskell-prime


Tuple-like constructors

2006-02-04 Thread Pablo Barenbaum
An awkwardness in Haskell I would like to see solved in
Haskell', is the fact that the behavior of tuple-like
constructors must be either built-in or limited.

As far as I can see, these are two issues:

1. There is not a way, for the programmer, to define
infinite constructors for infinite associated types (such as
(,) (,,) (,,,) ... / (a, b) (a, b, c) (a, b, c, d) ...)
these must be built-in.

2. There is not a way to define functions operating on all
of these types. Instead, different functions (like zip,
zip3) must be defined. Something similar happens with
liftM, liftM2, ... these are limited.

It seems the language is lacking abstraction, or being
misused, when the standard prelude issues this code:

  zip  :: [a] - [b] - [(a,b)]
  zip   = zipWith  (\a b - (a,b))

  zip3 :: [a] - [b] - [c] - [(a,b,c)]
  zip3  = zipWith3 (\a b c - (a,b,c))

Clearly, at least for a human being, it's redundant.
I don't know if there already are proposals to solve this.

Sorry if I sound aggresive, I'm just trying to help.
Excuse my English...

Best regards.

--
Pablo Barenbaum
___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://haskell.org/mailman/listinfo/haskell-prime


Re: Tuple-like constructors

2006-02-04 Thread Robert Dockins


On Feb 4, 2006, at 7:56 PM, Pablo Barenbaum wrote:


An awkwardness in Haskell I would like to see solved in
Haskell', is the fact that the behavior of tuple-like
constructors must be either built-in or limited.


One thing I recall seeing on haskell-cafe some time back was the  
notion that an n-tuple is semantically equivalent to n nested right- 
strict 2-tuples (essentially right-strict heterogeneous lists).   
Perhaps we should consider the idea of the tuple notation simply  
being syntactic sugar for nested right-strict 2-tuples.  Consider:


data Tuple a b = Tuple a !b

-- (a,b)=== Tuple a (Tuple b ()) 
-- (a,b,c) === Tuple a (Tuple b (Tuple c ()))

-- etc...

fst (Tuple x _) = x
snd (Tuple x (Tuple y _)) = y

fst ('a',b') = 'a'
snd (a','b) = 'b'

fst ('a','b','c') = 'a'
snd ('a','b','c') = 'b'

fst ('a','b','c','d','e','f') = 'a'
-- etc...

It seems like compiler cleverness could recover the identical  
strictness and unboxing information available now when the shape of  
the tuple is known at compile time.





As far as I can see, these are two issues:

1. There is not a way, for the programmer, to define
infinite constructors for infinite associated types (such as
(,) (,,) (,,,) ... / (a, b) (a, b, c) (a, b, c, d) ...)
these must be built-in.

2. There is not a way to define functions operating on all
of these types. Instead, different functions (like zip,
zip3) must be defined. Something similar happens with
liftM, liftM2, ... these are limited.

It seems the language is lacking abstraction, or being
misused, when the standard prelude issues this code:

  zip  :: [a] - [b] - [(a,b)]
  zip   = zipWith  (\a b - (a,b))

  zip3 :: [a] - [b] - [c] - [(a,b,c)]
  zip3  = zipWith3 (\a b c - (a,b,c))

Clearly, at least for a human being, it's redundant.
I don't know if there already are proposals to solve this.

Sorry if I sound aggresive, I'm just trying to help.
Excuse my English...

Best regards.

--
Pablo Barenbaum
___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://haskell.org/mailman/listinfo/haskell-prime



Rob Dockins

Speak softly and drive a Sherman tank.
Laugh hard; it's a long way to the bank.
  -- TMBG


___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://haskell.org/mailman/listinfo/haskell-prime