From mark@felinemail.zzn.com Mon Sep 1 12:37:29 2003
From: mark@felinemail.zzn.com (Mark Espinoza)
Date: Mon, 1 Sep 2003 06:37:29 -0500
Subject: Haskell 6.0 install
Message-ID: <4B84EA44ED049C94C8E2BEABAB4DD5BA@mark.felinemail.zzn.com>
Hello,
I let make run while I was sleeping on my redhat 7.3 system and in
the morning it seemed to have worked. I ran make install which also
seemed to work. Now when I type ghc --help it tells me about
"ghc-5.04.2". Does this mean that I am still running ghc 5? What can I
do if I am still running ghc 5? Will it cause me any serious problems
if I start going through "An Introduction To Functional Programming
Systems Using Haskell" and deal with it later? Thanks.
Sincerely,
Mark
Get your free e-mail address at http://felinemail.zzn.com
__________________
http://www.zzn.com
From droundy@abridgegame.org Mon Sep 1 13:08:55 2003
From: droundy@abridgegame.org (David Roundy)
Date: Mon, 1 Sep 2003 08:08:55 -0400
Subject: Haskell 6.0 install
In-Reply-To: <4B84EA44ED049C94C8E2BEABAB4DD5BA@mark.felinemail.zzn.com>
References: <4B84EA44ED049C94C8E2BEABAB4DD5BA@mark.felinemail.zzn.com>
Message-ID: <20030901120854.GB714@jdj5.mit.edu>
On Mon, Sep 01, 2003 at 06:37:29AM -0500, Mark Espinoza wrote:
> Hello,
>
> I let make run while I was sleeping on my redhat 7.3 system
> and in the morning it seemed to have worked. I ran make install
> which also seemed to work. Now when I type ghc --help it tells
> me about "ghc-5.04.2". Does this mean that I am still running
> ghc 5? What can I do if I am still running ghc 5? Will it
> cause me any serious problems if I start going through "An
> Introduction To Functional Programming Systems Using Haskell"
> and deal with it later? Thanks.
You can try running with ghc6 rather than ghc. ghc 6 and 5 can be
installed in parallel without problems, and if you're writing pure haskell
98 with no extensions (as I imagine the book does), you should be able to
use either one with no problems.
--
David Roundy
http://www.abridgegame.org
From ganesh@earth.li Mon Sep 1 14:52:19 2003
From: ganesh@earth.li (Ganesh Sittampalam)
Date: Mon, 01 Sep 2003 14:52:19 +0100
Subject: IO StateTransformer with an escape clause
In-Reply-To: <200308261433.28038.thomas_bevan@toll.com.au>
References: <200308261433.28038.thomas_bevan@toll.com.au>
Message-ID: <5lj6lvg97rq98boudqj3idg6i9epmi8u32@4ax.com>
On Tue, 26 Aug 2003 14:33:28 +1000, "Thomas L. Bevan"
wrote:
>Hi,
>
>I'd like some help building an IO StateTransformer which can be escaped midway
>through without losing the state accummulated up to that point.
>I tried constructing a
> StateT s MaybeIO a monad but the state is lost when the rest of
>the monad collapses.
How is your MaybeIO type constructed? If with a monad transformer, then you
could consider putting the MaybeT transformer outside the StateT transformer
(I think that should work).
Ganesh
From m.p.donadio@ieee.org Wed Sep 3 00:54:51 2003
From: m.p.donadio@ieee.org (Matthew Donadio)
Date: Tue, 02 Sep 2003 19:54:51 -0400
Subject: OT - Book on Programming
Message-ID: <3F552DCB.BF6F31DA@comcast.net>
Hi all,
This is a little off-topic, but I know there are a lot of people here
with teaching experience.
I am looking for a good book on programming. I recently picked up a gig
doing ActionScript programming for a multimedia company. They have very
good designers, but not very good programmers. So, they decided to hire
a professional programmer to help them out with some of their projects.
They have several people in the company who understand the mechanics of
programming, but don't really understand the concepts. I am looking for
a book to recommend to them. I would really like to find a book that
just discusses programming, and avoids any one particular language. It
would have to cover the common imperative controls, as well as basic
data structures.
Thanks.
--
Matthew Donadio (m.p.donadio@ieee.org)
From dvanhorn@cs.uvm.edu Wed Sep 3 01:19:02 2003
From: dvanhorn@cs.uvm.edu (David Van Horn)
Date: Tue, 02 Sep 2003 19:19:02 -0500
Subject: OT - Book on Programming
In-Reply-To: <3F552DCB.BF6F31DA@comcast.net>
References: <3F552DCB.BF6F31DA@comcast.net>
Message-ID: <3F553376.1070500@cs.uvm.edu>
How to Design Programs: An Introduction to Programming and Computing by
Felleisen, Findler, Flatt, and Krishnamurthi is rather good at introducing the
fundamentals of programming in my opinion. I've given the book to friends of
mine with no background in programming or computer science and they've found
it quite accessible. The text is freely available on-line too.
http://htdp.org/
The book is about the general design of programs, but uses Scheme as a
teaching language, and the DrScheme environment (also freely available) is
tailored for use with the book.
If your audience has any background in programming, they should be able to
move through the text quickly.
HTH
-d
From Tom.Pledger@peace.com Wed Sep 3 04:35:03 2003
From: Tom.Pledger@peace.com (Tom Pledger)
Date: Wed, 3 Sep 2003 15:35:03 +1200
Subject: Poll result: How to respond to homework questions
In-Reply-To: <16205.9696.324126.137830@tux-17.corp.peace.com>
References: <16205.9696.324126.137830@tux-17.corp.peace.com>
Message-ID: <16213.24935.818437.201078@tux-17.corp.peace.com>
Hi.
The stream of votes has dried up, and the ICFP people and monthly
digest people have had an opportunity, so here's the collated result.
22 people voted.
(A) Give a perfect answer.
(B) Give a subtly flawed answer.
(C) Give an obfuscated answer.
(D) Give a critique of what the questioner has tried so far,
or ask to see what the questioner has tried so far.
(E) Give relevant general advice without answering the specific question.
Approve Neither Disapprove
A 1 6 15
B 1 4 17
C 3 4 15
D 20 2 0
E 21 1 0
Combination Count
+ADE -BC 1
+BDE -A 1
+C 1
+CDE -AB 2
+DE 3
+DE -ABC 11
+DE -BC 2
+E -ABC 1
Notes
-----
Some votes were made conditional on the tone and content of the
question. I smoothed these out for ease of collation, e.g. "+ADE -BC
if ..., otherwise +DE -ABC" became +DE -BC.
15 of the votes were accompanied by some descriptive text. There's
not much I can do to tabulate that extra information, but here are a
couple of the things I thought stood out.
- Some of the 11 like-minded people showed clearly that they're
university staff: they gave longer forms of their email signatures
than they normally use for posting to lists @haskell.org.
- "D and E are what I do when a student fronts up to my office
wanting help with homework I've set. I'd have no problem with
(informed) third parties doing the same."
(If you sent me descriptive text, didn't keep a copy yourself, and
were expecting me to relay it to everyone, please let me know.)
- Tom
From ajb@spamcop.net Wed Sep 3 06:52:10 2003
From: ajb@spamcop.net (Andrew J Bromage)
Date: Wed, 3 Sep 2003 15:52:10 +1000
Subject: Help on Homework help
Message-ID: <20030903055210.GA27774@smtp.alicorna.com>
G'day all.
In response to the recent poll, and because I promised to, here is a
first attempt at a page to direct people to, should they ask for
homework help in the wrong way:
http://haskell.org/hawiki/HomeworkHelp
Comments, criticisms and contributions are most welcome.
Cheers,
Andrew Bromage
From simonpj@microsoft.com Wed Sep 3 08:34:58 2003
From: simonpj@microsoft.com (Simon Peyton-Jones)
Date: Wed, 3 Sep 2003 08:34:58 +0100
Subject: Help on Homework help
Message-ID: <4B93206CA3C55D4F96A61C9B1DC80DE33B5A8F@EUR-MSG-03.europe.corp.microsoft.com>
Good write-up.
One suggestion: it'd be good to suggest *strongly* that people only send =
their homework-style questions to Haskell-caf=E9, not to the main =
Haskell list. Given the existence of the fomer, using the latter is =
likely to irritate, which isn't likely to elicit helpful responses.
I know I could make the change myself, but you'll do it better :-)
Simon
| -----Original Message-----
| From: haskell-cafe-admin@haskell.org =
[mailto:haskell-cafe-admin@haskell.org] On Behalf Of Andrew
| J Bromage
| Sent: 03 September 2003 06:52
| To: haskell-cafe@haskell.org
| Subject: Help on Homework help
|=20
| G'day all.
|=20
| In response to the recent poll, and because I promised to, here is a
| first attempt at a page to direct people to, should they ask for
| homework help in the wrong way:
|=20
| http://haskell.org/hawiki/HomeworkHelp
|=20
| Comments, criticisms and contributions are most welcome.
|=20
| Cheers,
| Andrew Bromage
| _______________________________________________
| Haskell-Cafe mailing list
| Haskell-Cafe@haskell.org
| http://www.haskell.org/mailman/listinfo/haskell-cafe
From ajb@spamcop.net Wed Sep 3 08:44:03 2003
From: ajb@spamcop.net (Andrew J Bromage)
Date: Wed, 3 Sep 2003 17:44:03 +1000
Subject: Help on Homework help
In-Reply-To: <4B93206CA3C55D4F96A61C9B1DC80DE33B5A8F@EUR-MSG-03.europe.corp.microsoft.com>
References: <4B93206CA3C55D4F96A61C9B1DC80DE33B5A8F@EUR-MSG-03.europe.corp.microsoft.com>
Message-ID: <20030903074403.GA29516@smtp.alicorna.com>
G'day all.
On Wed, Sep 03, 2003 at 08:34:58AM +0100, Simon Peyton-Jones wrote:
> One suggestion: it'd be good to suggest *strongly* that people only
> send their homework-style questions to Haskell-café, not to the main
> Haskell list.
Done, thanks.
Cheers,
Andrew Bromage
From shae@ScannedInAvian.com Wed Sep 3 08:44:51 2003
From: shae@ScannedInAvian.com (Shae Matijs Erisson)
Date: Wed, 03 Sep 2003 09:44:51 +0200
Subject: OT - Book on Programming
In-Reply-To: <3F552DCB.BF6F31DA@comcast.net> (Matthew Donadio's message of
"Tue, 02 Sep 2003 19:54:51 -0400")
References: <3F552DCB.BF6F31DA@comcast.net>
Message-ID: <87r82y71u4.fsf@thunderbird.webwitches.com>
Matthew Donadio writes:
> They have several people in the company who understand the mechanics of
> programming, but don't really understand the concepts. I am looking for
> a book to recommend to them. I would really like to find a book that
> just discusses programming, and avoids any one particular language. It
> would have to cover the common imperative controls, as well as basic
> data structures.
I'd also recommend "The Pragmatic Programmer"
http://www.pragmaticprogrammer.com/ppbook/index.shtml
It's difficult to summarize, but I think every programmer should read it at
least once. It is mostly about the mechanics of programming also.
--
Shae Erisson - this space for rent - #haskell on irc.freenode.net
"Notwithstanding fervent argument that patent protection is essential
for the growth of the software industry, commentators have noted
that `this industry is growing by leaps and bounds without it.'"
-- US Supreme Court Justice John Paul Stevens, March 3, 1981.
From wvasconc@csd.abdn.ac.uk Wed Sep 3 09:30:18 2003
From: wvasconc@csd.abdn.ac.uk (Wamberto Vasconcelos)
Date: Wed, 3 Sep 2003 09:30:18 +0100
Subject: Problem with Infinite Lists
Message-ID: <1062577818.3f55a69aeb66a@www.csd.abdn.ac.uk>
Folks
I am new in this forum, so apologies if this has been asked before. If this is
the case, please point me to the direction of the answer and I won't bother you
again!
Also, could you make sure you CC your answers to me? I am not sure how long it
takes for my subscription to be activated and I don't want to miss out on the
action :-)
The Problem
I have defined this function to calculate the Fibonacci numbers:
all_fib :: [Float]
all_fib = 1:(1:(add_fib all_fib))
where add_fib (x:y:rs) = (x + y):(add_fib (y:rs))
Which seems to work:
Main> take 20 all_fib
[1.0,1.0,2.0,3.0,5.0,8.0,13.0,21.0,34.0,55.0,89.0,144.0,233.0,377.0,
610.0,987.0,1597.0,2584.0,4181.0,6765.0]
However, when I tried
Main> filter even (take 20 all_fib)
ERROR - Illegal Haskell 98 class constraint in inferred type
*** Expression : filter even (take 20 all_fib)
*** Type : Integral Float => [Float]
What is going on here?
Thanks in advance for any help/hint.
--
Wamberto Vasconcelos, PhD wvasconcelos@acm.org
Department of Computing Science http://www.csd.abdn.ac.uk/~wvasconc
University of Aberdeen, Aberdeen AB24 3UE, Scotland, UK
Phone +44 (0)1224 272283 Fax +44 (0)1224 273422
From hinsen@cnrs-orleans.fr Wed Sep 3 11:51:21 2003
From: hinsen@cnrs-orleans.fr (Konrad Hinsen)
Date: Wed, 3 Sep 2003 12:51:21 +0200
Subject: Problem with Infinite Lists
In-Reply-To: <1062577818.3f55a69aeb66a@www.csd.abdn.ac.uk>
References: <1062577818.3f55a69aeb66a@www.csd.abdn.ac.uk>
Message-ID: <200309031251.21245.hinsen@cnrs-orleans.fr>
On Wednesday 03 September 2003 10:30, Wamberto Vasconcelos wrote:
> Which seems to work:
>
> Main> take 20 all_fib
> [1.0,1.0,2.0,3.0,5.0,8.0,13.0,21.0,34.0,55.0,89.0,144.0,233.0,377.0,
> 610.0,987.0,1597.0,2584.0,4181.0,6765.0]
>
> However, when I tried
>
> Main> filter even (take 20 all_fib)
> ERROR - Illegal Haskell 98 class constraint in inferred type
> *** Expression : filter even (take 20 all_fib)
> *** Type : Integral Float =3D> [Float]
>
> What is going on here?
"even" wants an integral type for its argument, but you are applying it t=
o a=20
list of floats.
Konrad.
From steffen.mazanek@unibw-muenchen.de Wed Sep 3 11:50:38 2003
From: steffen.mazanek@unibw-muenchen.de (Steffen Mazanek)
Date: Wed, 03 Sep 2003 12:50:38 +0200
Subject: Problem with Infinite Lists
In-Reply-To: <1062577818.3f55a69aeb66a@www.csd.abdn.ac.uk>
References: <1062577818.3f55a69aeb66a@www.csd.abdn.ac.uk>
Message-ID: <3F55C77E.8050603@unibw-muenchen.de>
Hello,
>all_fib :: [Float]
>
>
>
You define "all_fib" to return a list of "Float", but "even" does only work
for numbers whose type is an instance of the class Integral, e.g. Int.
HTH and ciao,
Steffen
From gwright@comcast.net Wed Sep 3 14:11:28 2003
From: gwright@comcast.net (Gregory Wright)
Date: Wed, 3 Sep 2003 09:11:28 -0400
Subject: OT - Book on Programming
In-Reply-To: <3F552DCB.BF6F31DA@comcast.net>
Message-ID: <21170FAA-DE10-11D7-84AE-00039398F084@comcast.net>
On Tuesday, September 2, 2003, at 07:54 PM, Matthew Donadio wrote:
>
> They have several people in the company who understand the mechanics of
> programming, but don't really understand the concepts. I am looking
> for
> a book to recommend to them. I would really like to find a book that
> just discusses programming, and avoids any one particular language. It
> would have to cover the common imperative controls, as well as basic
> data structures.
>
In my previous company, I recommended Thomas Standish's
_Data Structure Techniques_. It's out of print, but easily (and
inexpensively)
available at Amazon. I like the original 1980 edition; his later
_Data Structure Techniques in Java_ is too closely tied to the
Java language.
It covers the usual data structures (lists, trees, strings, etc.) using
pseudocode algorithms. It's at the right level for someone who has
gotten the hang of programming at the level of compiling and
debugging simple programs and is ready to move onto something
more complicated.
Best Wishes,
Greg
Gregory Wright
Antiope Associates
18 Clay Street
Fair Haven, New Jersey 07704
USA
gwright@antiope.com
From hinsen@cnrs-orleans.fr Wed Sep 3 14:13:30 2003
From: hinsen@cnrs-orleans.fr (Konrad Hinsen)
Date: Wed, 3 Sep 2003 15:13:30 +0200
Subject: Histograms
Message-ID: <200309031513.30989.hinsen@cnrs-orleans.fr>
How would one best (read: most efficiently) create a histogram in Haskell=
?=20
More precisely, given a list of integers in a known range, I want a count=
of=20
how often any given number occurs.
In imperative languages this would be done by iterating over the list and=
=20
updating the count for the element under consideration. Without updatable=
=20
data structures, the most straightforward solution I can think of would s=
tart=20
by sorting the list, but for a long list that is very inefficient.
Any suggestions?
Konrad.
From wferi@afavant.elte.hu Wed Sep 3 14:51:25 2003
From: wferi@afavant.elte.hu (Ferenc Wagner)
Date: Wed, 03 Sep 2003 15:51:25 +0200
Subject: Histograms
In-Reply-To: <200309031513.30989.hinsen@cnrs-orleans.fr> (Konrad Hinsen's
message of
"Wed, 3 Sep 2003 15:13:30 +0200")
References: <200309031513.30989.hinsen@cnrs-orleans.fr>
Message-ID: <3o65ka9e02.fsf@tba.elte.hu>
Konrad Hinsen writes:
> How would one best (read: most efficiently) create a
> histogram in Haskell?
Check out accumArray.
Feri.
From henning@ikso.net Wed Sep 3 15:28:18 2003
From: henning@ikso.net (henning@ikso.net)
Date: Wed, 3 Sep 2003 14:28:18 -0000 (UTC)
Subject: haskell html-colorizer
Message-ID: <35235.129.16.235.160.1062599298.squirrel@retposhto.ikso.net>
Are anyone aware of a haskell html-colorizer a' la the emacs-mode?
Regards
/Henning
From droundy@jdj5.mit.edu Wed Sep 3 15:39:40 2003
From: droundy@jdj5.mit.edu (David Roundy)
Date: Wed, 3 Sep 2003 10:39:40 -0400
Subject: haskell html-colorizer
In-Reply-To: <35235.129.16.235.160.1062599298.squirrel@retposhto.ikso.net>
References: <35235.129.16.235.160.1062599298.squirrel@retposhto.ikso.net>
Message-ID: <20030903143938.GX15540@jdj5.mit.edu>
On Wed, Sep 03, 2003 at 02:28:18PM -0000, henning@ikso.net wrote:
> Are anyone aware of a haskell html-colorizer a' la the emacs-mode?
I've never used it, but webcpp may be what you're looking for.
http://webcpp.sourceforge.net/
--
David Roundy
http://civet.berkeley.edu/droundy/
From Malcolm.Wallace@cs.york.ac.uk Wed Sep 3 15:49:47 2003
From: Malcolm.Wallace@cs.york.ac.uk (Malcolm Wallace)
Date: Wed, 3 Sep 2003 15:49:47 +0100
Subject: haskell html-colorizer
In-Reply-To: <35235.129.16.235.160.1062599298.squirrel@retposhto.ikso.net>
References: <35235.129.16.235.160.1062599298.squirrel@retposhto.ikso.net>
Message-ID: <20030903154947.08c84e68.Malcolm.Wallace@cs.york.ac.uk>
This is a multi-part message in MIME format.
--Multipart_Wed__3_Sep_2003_15:49:47_+0100_08397710
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
writes:
> Are anyone aware of a haskell html-colorizer a' la the emacs-mode?
I wrote one a few months ago, but never released it. So here it
is, released at last as version 1.0. (It can also do ANSI terminal
colouring, if you are interested.)
Regards,
Malcolm
--Multipart_Wed__3_Sep_2003_15:49:47_+0100_08397710
Content-Type: application/octet-stream;
name="hscolour-1.0.tar.gz"
Content-Disposition: attachment;
filename="hscolour-1.0.tar.gz"
Content-Transfer-Encoding: base64
H4sIAAv/VT8AA+07/VMbO5L5dfVX6ObthfFhO+YrvPOL2UcICewjIRWSTaWABeGRbRXjGTOaCfhC
9m+/7pY0XzYhW8tL3e2zqszMqFvdra/+khjpfhzGWdJaaXeePPp9Sqez3tnc2IBnZ3VlcxWfnc6K
fZryqLO5ubqxtrnZWV95BLCN1c1HfON3kqdSMp2KhPNHYxHCSIzvxLseSRn+CIF+bBmV57/tvh6W
R2el03m6vn7n/G+ub9Tmf31tc+UR7zysGPPLH3z+d2i+3yZyoBnnX/ilnF7HScB5jx9/iAKZwIpI
ZPMl/BkmcRYF/FUiZXQKyE1EHobTyQiRSxjvZGDgoZjGWcp5Db4zFZZAPx6PZZTWEZ6HmXQIkQJh
COFNnMAkmfrPIplbD/jxxNY/j8OgOU8saJwjzRVLp4mKhjMIr8UQhBWW0wiXzbdxomx8IZNv42gZ
yn6q4igXmd+Fip0WUVpp8UKNKw2gk01eTBw2/Mq+Mf+V/b/95mgfdMBDr7F79j9s+7Xa/l97urq6
2P8/orRa/K1IUiXCcMpTcSkjPkjiMd/LhppvR1od9XG/w6rgobpIRDLtsnEcZKHkuFpgefl8pIaj
EH7pYUTrtPgeDKoVZueEUiQyDu3bRf4Wqkja1xfxdWRfP0zwRVPTYZzGhkaW6NiA6M3i0/uBHKTu
/V3OVYvP8m2sFW6cJk+kTmF7uArC2HNS+u12g2qMcsw/zU7ZmYJY9C0jcRFKGKA4DN/JIRHW9IWC
mTcUzOhC6NzHREyY6YhM38tkrCIRHqn/kX+Caeh2+f4h9/ejtAm/BgzstQrSUXMkUSaUoMFhESaS
MTWexEnKD5ROua+iFDb7BH6yqTRqcnVzOGg4pHdZBKSSLNqOgndSBEdpADo5B++gGvOVfqGGqlRL
Pc0HhDEGAj4XWvWxW7AeUNGm0D94BlJ3GUunE8lhOHlRekVnGBOpq4Z+Il5rix8ZNZu/MZzeHAna
Icg+LMYoHsscw9bB4uD1OuTn3zSnDa5RECJ8w6d8eZlrln+RkEsnu0c7S92l46Wur0fxNWH5S78s
denrBtt4e16jUWKe01zhK4y5xWjqPaR3vO2xYmUW1c9dNS3MvHrHVePaLbBfeEDc7pYy8d885rZO
uXrF1eNaK9WvunojS17/V1ttJC/IQD1M984ojrWEJaf6I/kZzFg84OlI8gGs6vgaJw7ZaK4015lK
cSsALOFg8hOupzqV425pbkri/NWjb+CB+G93+LVKR6RO2kefjoB3vdXfD7z827Y6gmUNQgTxNWPl
rV1itOmx2jZ3kJ89s6IDkQq71i1ps/5lYJRgfRu4JnnN/U2YisDARH3Jd8EbKLU0W5lTKwIZNybv
dacMQ7+gNCIrZRh4AOU9t1qGFY4AwdYrNGH6Lot2G2XYO5xwLf+mAhkDbLMM24mhNyKU1v36uQzz
S55IvwHQtQ5fLsD9Cu5z0b8s467XcFluNnBjH+dDdzpXdxTIIk0TWJNAsWSYbC3uf/xTMVGsjHd8
agekUul8zFmK+bL2GJ9XgBnoyr6oamru/eJxfywmnHRO23W7Yag2GncR88YeKwufs++M7aLejriK
BipSqYSNOZmAXYeda2yXbrOSEaNhNQv2tFLf4316HqM3ic540/qhTXL+m8ZTJm7G+uEEzFrDO7X4
HFT0wlKwqEExnsvLpIAJsrycK2TAgWFIoLeFhc1nATSms8AlTfDaI1kPQF+1rsEGT3DpgBcjmbPK
/H2SyWIuN0deAXopQi0LUGiIvQTlw8lCcwFvxkqTjrR23VpKVjP1dTs/A+/xIKbZhyiEP2vxuunm
Hmg1RGxlZsmFMuUhLnejj6EZVScyzZKI+wMU1Ns5PPjw+s2RB5hNbqoO9t/sUgUuNqeOuAHecLsR
jCLKa33d1brBb+H1vHA2zmm3JSAisgthBLj1KLiet5JveQyWJLlWumRPLQetTef5OboYAroU7Efn
KE3PzMRc8M2v/ln3RqMa0VXJoCe3t7P4mn0rKvrjlEr8VzNeDxUK3pf/2VhbrcV/T1c21hbx348o
Nparuy0Y1tWin3p4lEcjZS+qB24FmHXY4WA64C/ZC3h+kug0wgtaE3hYewJvaEvg8XEE9gqogr+i
PqN69nevmkeg75uo+ZpkGy2rwofqkS4wtpmhWkE/iV7AKaJn4QAZOPo89Fb2cKgid2voq5wWop6Z
5oXHktfOF7jx/0W9zNn/oJUfNgl0z/6HTV/P/2501jYW+/9HlMr+V2RdfX6nUnApEZcvbpLRr9f1
S8TqOYs6TVt9RPEi98EZ2o0+V7IT5WxHRdkQQ9A4d6Swi/S0S0Tn+eYitWwzyTZxbFPDpRywyfO6
TG41YTsnIVuNUzD3erd+CORAZGH6XX2pZ5CNG15N8/5fT8fXktSoqv+g6XhW2zQ2JCjPfR0DIjKR
9ke4O4MYOIcUGQDSSwUb1csP7lwQ6px/8skBnQJK/0RCDOYIGVKU0wJaZuNxb+/w9W4RydYZ+YgO
0VdxUugV/v1cno6rBc4uesBiucLAkSh3uxLoH/vmvVnaYo3TUuMJtIGRoqj6RLe2fN3sh0JrNZga
GDDjbT5EF6TN0/hSRqikKDSUN3xP6EtwU7gGcn1JmU2IpNOYC4OL61CKMXMNi3QjSWdeTwuwC6CO
S3V+v0vhk9JHE4FM6tFRj1B0o5vLR7lqo0Uh/NJN/KQ4ZwKOk6OjCxba0oGKO4hAZU5lREEbjHaY
BbIdwjBAxIYj8gpHScurTIJfpCmwRVraDMkYU0qZloMs5BdhfKGhCY2rf9X12l436hoGt6TC20p/
mExg6/nE7qqB+e6rTIRqoMBNjMRYIoF5GY+emS7fv4Jl1/aWlyMYGqLNDMA79yyv3p+gAJVz0kbn
OClOnfcFDAHh0zjEA7Myr6Ju0RzQkdjy8lUErM494JO3IPSzimAWvSqMiY5dkCtgMfm93lJrqcE1
iSYpY+5s0Gxffb28bLNF/Rn+1WLnsp/P5AUszkvuL51ES+egksbnDYyl7SB98bpeyzPS9fC7BR2t
sEDxInjCfNwt4QxTbOGsRqfgVx4HWKmWjQPbFJsDw/5gZTpF1sjtKRpst/ltXaPSJqr28ZZHW70O
9tR1VTeayfiOrNrcLmrEr/XQj5ZXaFTrrIGt97Vg3eGGdevrA7JufQ/rnuk1cm5CVR27uj7zMdIP
JWU0KyElbmSSxAn3opj3w1ijxnQIIChjX1rGr3uPGuY9niRhZPebnH5E3+cW316RY3PLD4wPg/Ga
IUCR2z5i/U0k9ITvw4n5xidQslraaiN4vDGewC3fRcFqUVyDtb6SCtxxxsNoPpYbk29aqZL/V7M+
v/qj7pkZ4sICjKqjW3GgZpRIGc+NINK2uF6r5dXycnZCHz/mIpoW5mIuFVIBccpBqYdTgCQJODaO
9JcZ0neKoblRQM571Y6Z82bvwCXnVRe4xpmdh2w8WfT5NCFbz7aE6izOzPAaF7aCeRBfz8M0Tm0J
c+TY6+n4Ig51GRM82DImTFh3aWbr9KxDXMM8n4c5l6Y3D9O6xzXUk6UZ3J7xkit9N1namb5bV7mE
OpOxzdnn/i9h48ZxnpSbf5YvBNzXxx6aY6/p0faAJ+59fBjfkN7MbsTXGP7IEPDR5/bUAD5NQIgv
Ef2BBemeoXtJ6MUcvcFrKBHfxLWGUiSv8cwaamOkCb1DYraKdBw8z+A3AFdHDRHY78NmhKfQ3ikr
1qvpU7sNkG4X/vTgd3ICf27h96wFf1pb8OdX+P0DwfhxDL9ToFJeyEiHfNfu8WmDe798+eo3mh5z
iw3B3n/89Of/fPxfy+0nz3pbf/n15OTvt61/eP9KqqmS/9nTRq098B2ge/I/q5tPV+r3/56uri/y
Pz+i2OQK3eWppGgwMqokZxgbCxW546kJxoUG0IbY8W0SD9+AGw8QUYVsJ0M0QmQBbShZTXKQby6c
T172DcGajmQIStBAvNbIO70LAl8EnIGk6dS0AogLc+ggVvTBqwIoidbICaXj0BGaRUdoGV+cloWF
cDqPlAXf2urxSZaCZ4DBpuVTlqqJrf+5ZiQdtvt2s1zMmbilPDzFkZ9jYy0Uhh9tUkWJxNTF+/ef
4LsaZ1O7nA/5nM/gbQscXoyxfQihnj2hilmfsj2Pyd771wd3cCGBcy/S9z5oMZRdDqwmwIYf42je
0tic8uMBjAfor1PgywrxwWOblz0onUkXuL5ujhrlCwBgHrUjRmJ+LzVCduQGcZSiLzjivtR9AU6u
jbT3cBR1mg0GzOHALnB+kM4rwXsc6QYdtWIVEsppaiJG1ZV7JJzQDY3qLRID8Z5d4JRpmi54NYiV
KyUOUY4LTHw3qJUbJg41KzAzh1i5bpIzx8qSAObTNKjcQan0o3IDpQKp3T8xTAiC6yrpuTsFfWBX
sEUEx7V2K6VE4WL4HTSYnVp/6dlSt0/n0d7jMP0F8CykrwucrQJneBfO4wJHjCfzkfqEQru3y2fA
uUqlULum/yv2/10W/Q7Xf++1/+sz9n/tKf7/x8L+//7FHvXAzNPJT/2yCSW60/EEteqc05wXCkPE
OJli1nccf5ZojRr1Qx1zGbC5e6PSnTiQeH4MyuonNQCPn5+d7T3fOTtzbT5EWgzkW5mA2z3ePyxh
bR/9tntw8N8/F7ivwO9QATPuR19qvf8C84Wm9icMGuowm4VeW9lYt/awxUVyoVK82OwOeX4C3a0G
+cMJ8GavJCZ8tPcPd2+goeZ+VhW6wWzMYO8GcgocuAfCTFTg8YpQJve/H6UzDF8dbB+9Ovzoel4w
J8YPzZZyvjICRydFfwImDGjgqODUY4aWZ5G6yiRPY56OlAb7TLTazC6Pajrc2kEHS+IYb7vWJOZ/
Ri9mYs8fcuG+IwlVnDZ4T4DHE1CLyMLmiEk/T4x1xfvPgusRxqOYq8DLWviDzY5xK1cwkrDQwXdq
s5mrVpUugbzOutfx+uOguLeF97EMRczC2wHwRmNxKcHvGaihOV8BbwY7ru0mARLozKBFMY2N30Te
MaJa/xgLbqSXQoUZGN0zlEzFu8Y1yrRM7Ku3YzvrYw6SiDf4AFrJwCtdL6T2biwb9m5V+cjHCGNv
lLkt7vpnruNixbWC8cXk0YW0eAHMdqrCghKm/vC+sCNmeOKCwMuK4MAgMUxmTDhsK4WXCjlE6XSZ
WQQBELyYmomsOK85gfzm5vFpDYA58dN5gBt3RHNTg/g39jbZDe8Wtf+Gt8aq9n93+8Xr3QfncZ/9
X9tYz+3/2uY62v/11cX///2Q4lI+Xb5dOwBt0QFoHo8lbdCm313YTjyZJhgWdTlf7XTWmvy1GWD+
EYyS6Es8Flfo4auULih/ipNLxp5nKgxg43dN5Ic6kzsRGTOBH4Fc5R3RH2PvRxhCxsNEjEGJRqXA
UtRPekmB4T8VSIVJzvwGL7Nazo8nlN9ETg0OeBTX1YEoQaPNOTK2qUwGZhLp5leCTZum+acKPD/F
67qgpEUSUAqm+O+aQFJThv9xkd/dZvsD0LFGXpEMM0q8A48hDGTUBM1KyrZEU0Vo1zg/NLIqzUR4
LaaaXycqTYERGPMc2VlB9inO7JChtUIrU5KCOgQOwwD0L3AP5Y0CN4PDu0oVCH0xZTKAV1DeIqcg
aIhIbvRJQJXnFwhARkM+S4hg4FzKNvO3Iy5vIOqBZgoPnvuYjglci0ChsbjIkHa7YQbeTeVY0MAI
6DDXiii4Sf8s8AwSz7PxoKmUi6LrKkAy6+MhaEbHVOj4BGygZBgAXGj73y/4H0+c33sX6btvI917
H+kbN5L+6TtJdAWlIv2/em3TUavfzCzdzSzdzizuZ87c0Czf0ZxzS7N+T/Oum5rz72r+u5nuRVmU
RVmURVmURVmURVmURVmURVmU7y7/C2X2/1QAUAAA
--Multipart_Wed__3_Sep_2003_15:49:47_+0100_08397710--
From chak@cse.unsw.edu.au Wed Sep 3 18:30:45 2003
From: chak@cse.unsw.edu.au (Manuel M T Chakravarty)
Date: Wed, 03 Sep 2003 19:30:45 +0200 (CEST)
Subject: haskell html-colorizer
In-Reply-To: <35235.129.16.235.160.1062599298.squirrel@retposhto.ikso.net>
References: <35235.129.16.235.160.1062599298.squirrel@retposhto.ikso.net>
Message-ID: <20030903.193045.925163789.chak@cse.unsw.edu.au>
> Are anyone aware of a haskell html-colorizer a' la the emacs-mode?
XEmacs has the very nice function
M-x htmlize-buffer
which when executed in a buffer containing a Haskell file
(or any other source code for which (X)Emacs provides
special markup) produces HTML output that exactly matches
the display used in (X)Emacs itself (ie, including colours).
I am unsure whether that or similar functionality is
provided by GNU Emacs, too, but it may very well be.
Cheers,
Manuel
From dvanhorn@emba.uvm.edu Wed Sep 3 18:45:19 2003
From: dvanhorn@emba.uvm.edu (David Van Horn)
Date: Wed, 03 Sep 2003 13:45:19 -0400
Subject: haskell html-colorizer
References: <35235.129.16.235.160.1062599298.squirrel@retposhto.ikso.net>
<20030903.193045.925163789.chak@cse.unsw.edu.au>
Message-ID: <3F5628AF.8070503@emba.uvm.edu>
Manuel M T Chakravarty wrote:
> XEmacs has the very nice function
>
> M-x htmlize-buffer
>
> which when executed in a buffer containing a Haskell file
> (or any other source code for which (X)Emacs provides
> special markup) produces HTML output that exactly matches
> the display used in (X)Emacs itself (ie, including colours).
>
> I am unsure whether that or similar functionality is
> provided by GNU Emacs, too, but it may very well be.
I don't believe it is provided with GNU Emacs, but it can be added on:
http://fly.cc.fer.hr/~hniksic/emacs/htmlize.el
-d
From john@repetae.net Wed Sep 3 18:50:46 2003
From: john@repetae.net (John Meacham)
Date: Wed, 3 Sep 2003 10:50:46 -0700
Subject: haskell html-colorizer
In-Reply-To: <35235.129.16.235.160.1062599298.squirrel@retposhto.ikso.net>
References: <35235.129.16.235.160.1062599298.squirrel@retposhto.ikso.net>
Message-ID: <20030903175046.GD25669@momenergy.repetae.net>
On Wed, Sep 03, 2003 at 02:28:18PM -0000, henning@ikso.net wrote:
> Are anyone aware of a haskell html-colorizer a' la the emacs-mode?
typing
:runtime! syntax/2html.vim
in gvim will cause it to spit out an html file with the exact same
syntax highlighting as used in the editor. quite handy. some versions of
nenscript can spit out highlighted html too, not sure if they support
haskell though.
John
--
---------------------------------------------------------------------------
John Meacham - California Institute of Technology, Alum. - john@foo.net
---------------------------------------------------------------------------
From obraun@unsane.org Wed Sep 3 18:51:09 2003
From: obraun@unsane.org (Oliver Braun)
Date: Wed, 3 Sep 2003 19:51:09 +0200
Subject: haskell html-colorizer
In-Reply-To: <20030903.193045.925163789.chak@cse.unsw.edu.au>
References: <35235.129.16.235.160.1062599298.squirrel@retposhto.ikso.net>
<20030903.193045.925163789.chak@cse.unsw.edu.au>
Message-ID: <20030903175109.GA46744@unsane.de>
--VbJkn9YxBvnuCH5J
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
* Manuel M T Chakravarty [2003-09-03 19:30 +0200]:
> > Are anyone aware of a haskell html-colorizer a' la the emacs-mode?
> XEmacs has the very nice function
> M-x htmlize-buffer
> which when executed in a buffer containing a Haskell file
> (or any other source code for which (X)Emacs provides
> special markup) produces HTML output that exactly matches
> the display used in (X)Emacs itself (ie, including colours).
Vim[1] has the same functionality. Just type
:runtime! syntax/2html.vim
in normal mode.
Regards,
Olli
1. http://vim.org/
--=20
Oliver Braun -- obraun @ { unsane.org | FreeBSD.org | haskell.org }
--VbJkn9YxBvnuCH5J
Content-Type: application/pgp-signature
Content-Disposition: inline
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (FreeBSD)
iD8DBQE/VioNwLFrfe8lsboRAjUeAKCS4P48kpmBh5hqPlQgNKPNtvynIACdHQAt
XWPNAwBm+nWbQlbhzsy2ZzY=
=dVYt
-----END PGP SIGNATURE-----
--VbJkn9YxBvnuCH5J--
From knarf@bka-inc.com Wed Sep 3 19:18:00 2003
From: knarf@bka-inc.com (Frank Seaton Taylor)
Date: Wed, 3 Sep 2003 14:18:00 -0400
Subject: Problem with Infinite Lists
In-Reply-To: <1062577818.3f55a69aeb66a@www.csd.abdn.ac.uk>
Message-ID:
This is a bit off topic, but...
Warning: contains evangelism from a number theorist.
The Fibonacci sequence should start with 0 and 1 rather than 1 and 1.
Doing so makes it adhere to the following property:
all_fib !! (gcd m n) == gcd (all_fib !! m) (all_fib !! n)
for m, n nonnegative integers. With the exception that Haskell
misdefines gcd 0 0 as an error rather than 0.
---Frank
On Wednesday, Sep 3, 2003, at 04:30 US/Eastern, Wamberto Vasconcelos
wrote:
> Folks
>
> I am new in this forum, so apologies if this has been asked before. If
> this is
> the case, please point me to the direction of the answer and I won't
> bother you
> again!
>
> Also, could you make sure you CC your answers to me? I am not sure how
> long it
> takes for my subscription to be activated and I don't want to miss out
> on the
> action :-)
>
> The Problem
>
> I have defined this function to calculate the Fibonacci numbers:
>
> all_fib :: [Float]
>
> all_fib = 1:(1:(add_fib all_fib))
> where add_fib (x:y:rs) = (x + y):(add_fib (y:rs))
>
> Which seems to work:
>
> Main> take 20 all_fib
> [1.0,1.0,2.0,3.0,5.0,8.0,13.0,21.0,34.0,55.0,89.0,144.0,233.0,377.0,
> 610.0,987.0,1597.0,2584.0,4181.0,6765.0]
>
> However, when I tried
>
> Main> filter even (take 20 all_fib)
> ERROR - Illegal Haskell 98 class constraint in inferred type
> *** Expression : filter even (take 20 all_fib)
> *** Type : Integral Float => [Float]
>
> What is going on here?
>
> Thanks in advance for any help/hint.
>
> --
> Wamberto Vasconcelos, PhD wvasconcelos@acm.org
> Department of Computing Science http://www.csd.abdn.ac.uk/~wvasconc
> University of Aberdeen, Aberdeen AB24 3UE, Scotland, UK
> Phone +44 (0)1224 272283 Fax +44 (0)1224 273422
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
From wolfgang@jeltsch.net Wed Sep 3 20:16:53 2003
From: wolfgang@jeltsch.net (Wolfgang Jeltsch)
Date: Wed, 3 Sep 2003 21:16:53 +0200
Subject: Problem with Infinite Lists
In-Reply-To: <3F55C77E.8050603@unibw-muenchen.de>
References: <1062577818.3f55a69aeb66a@www.csd.abdn.ac.uk>
<3F55C77E.8050603@unibw-muenchen.de>
Message-ID: <200309032116.53024.wolfgang@jeltsch.net>
Am Mittwoch, 3. September 2003 12:50 schrieb Steffen Mazanek:
> Hello,
>
> >all_fib :: [Float]
>
> You define "all_fib" to return a list of "Float", but "even" does only work
> for numbers whose type is an instance of the class Integral, e.g. Int.
>
> HTH and ciao,
> Steffen
And I see no reason to define it as a list of Float because all Fibonacci
numbers are natural numbers. So better write:
all_fib :: [Integer]
Wolfgang
From nick.name@inwind.it Thu Sep 4 00:46:15 2003
From: nick.name@inwind.it (Nick Name)
Date: Thu, 4 Sep 2003 01:46:15 +0200
Subject: Why not haskell?
Message-ID: <200309040146.15981.nick.name@inwind.it>
Inspired by the various replies to the "haskell for non-haskell sake" I
wonder why so much people uses haskell "only for prototipying" or
producing code in other languages.
I am just curios to hear from people who do not use haskell for project
releases, or just think it's not suitable for a mature project, what
exactly they find bad in current haskell implementations, or perhaps in
the standard.
Vincenzo
From db@zigo.dhs.org Thu Sep 4 05:27:51 2003
From: db@zigo.dhs.org (Dennis Bjorklund)
Date: Thu, 4 Sep 2003 06:27:51 +0200 (CEST)
Subject: haskell html-colorizer
In-Reply-To: <35235.129.16.235.160.1062599298.squirrel@retposhto.ikso.net>
Message-ID:
On Wed, 3 Sep 2003 henning@ikso.net wrote:
> Are anyone aware of a haskell html-colorizer a' la the emacs-mode?
GNU Enscript (1.6 and newer) can produce html and not just postscript and
it knows how to colorize haskell.
--
/Dennis
From GK@ninebynine.org Thu Sep 4 08:51:34 2003
From: GK@ninebynine.org (Graham Klyne)
Date: Thu, 04 Sep 2003 08:51:34 +0100
Subject: Why not haskell?
In-Reply-To: <200309040146.15981.nick.name@inwind.it>
Message-ID: <5.1.0.14.2.20030904084802.026e5538@127.0.0.1>
I would say that being a relatively niche technology would be a factor in
not using Haskell, because finding staff to handle software maintenance is
problematic.
Also, I think that memory usage and performance is still an issue (real or
imagined? My sense is that compiled Haskell can match widely languages
like Perl or Python, but not yet Java or C/C++).
#g
--
At 01:46 04/09/03 +0200, Nick Name wrote:
>Inspired by the various replies to the "haskell for non-haskell sake" I
>wonder why so much people uses haskell "only for prototipying" or
>producing code in other languages.
>
>I am just curios to hear from people who do not use haskell for project
>releases, or just think it's not suitable for a mature project, what
>exactly they find bad in current haskell implementations, or perhaps in
>the standard.
>
>Vincenzo
>
>_______________________________________________
>Haskell-Cafe mailing list
>Haskell-Cafe@haskell.org
>http://www.haskell.org/mailman/listinfo/haskell-cafe
------------
Graham Klyne
GK@NineByNine.org
From bjpop@cs.mu.OZ.AU Fri Sep 5 09:14:33 2003
From: bjpop@cs.mu.OZ.AU (Bernard James POPE)
Date: Fri, 5 Sep 2003 18:14:33 +1000 (EST)
Subject: haskell reify, was sequencing data structures
In-Reply-To: <3429668D0E777A499EE74A7952C382D1BE61B2@EUR-MSG-01.europe.corp.microsoft.com>
from Simon Marlow at
"Aug 26, 2003 04:05:27 pm"
Message-ID: <200309050814.SAA21851@mulga.cs.mu.OZ.AU>
> > However, the new debugger
> > in GHC must do something to get names of things, so perhaps the
> > -prof hack is no longer needed?
>
> I believe the debugger that Robert Ennals is working on tries to infer
> constructor names from the symbol table of the binary. Personally, I'd
> like to see debugging info placed in a separate segment of the binary,
> so it won't be loaded with the code but can be used by a debugger.
I wonder whether keeping the names of data constructors in info tables
is expensive?
I would have guessed not. (more debugging info such as
function names and src locations is likely to be more expensive however).
Anyway, would it be possible/feasible for GHC to keep names in info tables
all the time, not just for profiling? At least for data-constructors?
Cheers,
Bernie.
From simonmar@microsoft.com Fri Sep 5 10:39:47 2003
From: simonmar@microsoft.com (Simon Marlow)
Date: Fri, 5 Sep 2003 10:39:47 +0100
Subject: haskell reify, was sequencing data structures
Message-ID: <3429668D0E777A499EE74A7952C382D1C623E0@EUR-MSG-01.europe.corp.microsoft.com>
=20
> I wonder whether keeping the names of data constructors in info tables
> is expensive?
>=20
> I would have guessed not. (more debugging info such as
> function names and src locations is likely to be more=20
> expensive however).
>=20
> Anyway, would it be possible/feasible for GHC to keep names=20
> in info tables
> all the time, not just for profiling? At least for data-constructors?
That's a distinct possibility. If you send patches we'll incorporate
them.
Cheers,
Simon
From hinsen@cnrs-orleans.fr Fri Sep 5 15:35:01 2003
From: hinsen@cnrs-orleans.fr (Konrad Hinsen)
Date: Fri, 5 Sep 2003 16:35:01 +0200
Subject: Library documentation
Message-ID: <200309051635.01019.hinsen@cnrs-orleans.fr>
Is there any place where I can find an introductory documentation for the=
=20
Haskell libraries? To be more concrete, say I am interested in using=20
Data.Array.ST.STUArray. I would need some explanation of the ST monad, an=
d=20
then an explanation of how I can use an STUArray in an ST monad. Plus ide=
ally=20
examples. But the same applies to most of the libraries. I can't find any=
=20
documentation other than the very terse reference or the parts that happe=
n to=20
be covered by textbooks.
Konrad.
From per@L4i.se Fri Sep 5 16:17:59 2003
From: per@L4i.se (Per Larsson)
Date: Fri, 5 Sep 2003 17:17:59 +0200
Subject: Library documentation
In-Reply-To: <200309051635.01019.hinsen@cnrs-orleans.fr>
References: <200309051635.01019.hinsen@cnrs-orleans.fr>
Message-ID: <200309051717.59950.per@L4i.se>
On Friday 05 September 2003 16.35, Konrad Hinsen wrote:
> Is there any place where I can find an introductory documentation for t=
he
> Haskell libraries? To be more concrete, say I am interested in using
> Data.Array.ST.STUArray. I would need some explanation of the ST monad, =
and
> then an explanation of how I can use an STUArray in an ST monad. Plus
> ideally examples. But the same applies to most of the libraries. I can'=
t
> find any documentation other than the very terse reference or the parts
> that happen to be covered by textbooks.
>
> Konrad.
I have the same problem and as far as I know there is only haddock genera=
ted=20
html-documentation from sparse source comments available for many parts o=
f=20
the library. But for some of the modules you can get exactly the informa=
tion=20
you are asking for, e.g. the Parsec module has its own readable documenta=
tion=20
at http://www.cs.uu.nl/~daan/parsec.html and the Control.Monad module
has recently been superbly documented by John Newbern at=20
http://www.nomaware.com/monads/html/.
Best Regards
Per
From GK@ninebynine.org Fri Sep 5 18:29:49 2003
From: GK@ninebynine.org (Graham Klyne)
Date: Fri, 05 Sep 2003 18:29:49 +0100
Subject: Library documentation
In-Reply-To: <200309051635.01019.hinsen@cnrs-orleans.fr>
Message-ID: <5.1.0.14.2.20030905182622.00b82f08@127.0.0.1>
I think the GHC documentation is a place to look, though it is a bit sparse
in places. viz: http://www.haskell.org/ghc/docs/latest/html/base/index.html
Hmmm, it sounds as if you already found that. I mention it because I
didn't until someone pointed me at it.
#g
--
At 16:35 05/09/03 +0200, Konrad Hinsen wrote:
>Is there any place where I can find an introductory documentation for the
>Haskell libraries? To be more concrete, say I am interested in using
>Data.Array.ST.STUArray. I would need some explanation of the ST monad, and
>then an explanation of how I can use an STUArray in an ST monad. Plus ideally
>examples. But the same applies to most of the libraries. I can't find any
>documentation other than the very terse reference or the parts that happen to
>be covered by textbooks.
>
>Konrad.
>
>_______________________________________________
>Haskell-Cafe mailing list
>Haskell-Cafe@haskell.org
>http://www.haskell.org/mailman/listinfo/haskell-cafe
------------
Graham Klyne
GK@NineByNine.org
From mark@chaos.x-philes.com Tue Sep 9 16:21:06 2003
From: mark@chaos.x-philes.com (Mark Carroll)
Date: Tue, 9 Sep 2003 11:21:06 -0400 (EDT)
Subject: Why not haskell?
In-Reply-To: <200309040146.15981.nick.name@inwind.it>
Message-ID:
On Thu, 4 Sep 2003, Nick Name wrote:
> I am just curios to hear from people who do not use haskell for project
> releases, or just think it's not suitable for a mature project, what
> exactly they find bad in current haskell implementations, or perhaps in
> the standard.
We're not really there yet, but we're likely to have to code stuff that
works fast, guaranteed, with low overhead - for instance, in real-time
embedded systems for military sensor data processing. I don't know where
Haskell currently is, but I'm far from certain that it's up to that task.
-- Mark
From cmiltonperl@yahoo.com Tue Sep 9 16:54:57 2003
From: cmiltonperl@yahoo.com (Christopher Milton)
Date: Tue, 9 Sep 2003 08:54:57 -0700 (PDT)
Subject: Why not haskell?
In-Reply-To:
Message-ID: <20030909155457.60611.qmail@web20810.mail.yahoo.com>
--- Mark Carroll wrote:
> On Thu, 4 Sep 2003, Nick Name wrote:
>
> > I am just curios to hear from people who do not use haskell for project
> > releases, or just think it's not suitable for a mature project, what
> > exactly they find bad in current haskell implementations, or perhaps in
> > the standard.
>
> We're not really there yet, but we're likely to have to code stuff that
> works fast, guaranteed, with low overhead - for instance, in real-time
> embedded systems for military sensor data processing. I don't know where
> Haskell currently is, but I'm far from certain that it's up to that task.
What about Embedded Gofer? ;-) "Lambdas in the Liftshaft"
by Malcolm Wallace.
Then there's the DARPA-funded Project Timber at OGI:
http://www.cse.ogi.edu/PacSoft/projects/Timber/Default.htm
Chris Milton
From qrczak@knm.org.pl Tue Sep 9 19:56:48 2003
From: qrczak@knm.org.pl (Marcin 'Qrczak' Kowalczyk)
Date: Tue, 9 Sep 2003 20:56:48 +0200
Subject: Prefix and postfix operators
In-Reply-To: <9ED672B9D1A64C489291BE0FB822217D01FFAD4A@WIN-MSG-10.wingroup.windeploy.ntdev.microsoft.com>
References: <9ED672B9D1A64C489291BE0FB822217D01FFAD4A@WIN-MSG-10.wingroup.windeploy.ntdev.microsoft.com>
Message-ID: <200309092056.48949.qrczak@knm.org.pl>
Dnia ¶ro 27. sierpnia 2003 20:48, Eugene Nonko napisa³:
> Are there any plans to extend Haskell parser to support prefix and
> postfix operators? It will be just great for domain-specific languages.
> It always kind of bothered me that unary minus is special.
Having only infix operators has the advantage that operators are never
adjacent to other operators, so you don't need extra spaces just to
separate them nor complicated lexical conventions which tell where
multi-character operator sequences should be split. Especially as prefix
and postfix operators look better without spaces.
In Haskell there are rare troubles because of - and ~ (lazy patterns).
! (strictness annotations) happens not to be used adjacent to operators.
I think there are no more unary operators, so it's almost safe; problematic
cases with - and ~ are really rare.
--
__("< Marcin Kowalczyk
\__/ qrczak@knm.org.pl
^^ http://qrnik.knm.org.pl/~qrczak/
From listener@thaldyron.com Wed Sep 10 11:33:50 2003
From: listener@thaldyron.com (Peter Robinson)
Date: Wed, 10 Sep 2003 12:33:50 +0200
Subject: Standalone Parser for Haskell Grammar
Message-ID: <200309101233.51274.listener@thaldyron.com>
Hello!
Does anyone know a reasonable standalone Parser for the Haskell Grammar? The
only one i found was hsparser but it's still an alpha release and i get a few
errors during compiling. I know i could write one using Happy but i don't
want to reinvent the wheel...
regards
Peter
From ross@soi.city.ac.uk Wed Sep 10 12:39:50 2003
From: ross@soi.city.ac.uk (Ross Paterson)
Date: Wed, 10 Sep 2003 12:39:50 +0100
Subject: Standalone Parser for Haskell Grammar
In-Reply-To: <200309101233.51274.listener@thaldyron.com>
References: <200309101233.51274.listener@thaldyron.com>
Message-ID: <20030910113950.GA5677@soi.city.ac.uk>
On Wed, Sep 10, 2003 at 12:33:50PM +0200, Peter Robinson wrote:
> Does anyone know a reasonable standalone Parser for the Haskell Grammar? The
> only one i found was hsparser but it's still an alpha release and i get a few
> errors during compiling. I know i could write one using Happy but i don't
> want to reinvent the wheel...
The latest version of hsparser is the Language.Haskell.* modules in the
haskell-src package, included with recent releases of GHC and Hugs.
From listener@thaldyron.com Wed Sep 10 15:45:59 2003
From: listener@thaldyron.com (Peter Robinson)
Date: Wed, 10 Sep 2003 16:45:59 +0200
Subject: Standalone Parser for Haskell Grammar
Message-ID: <200309101646.00702.listener@thaldyron.com>
Thanks to both of you,
you helped me a lot! :-)
Peter
On Wednesday 10 September 2003 14:56, you wrote:
> You may find an error correcting combinator based parser in the
> directory uust, to be found at cvs.cs.uu.nl
>
> Just check out the whole tree and follow the building and installing
> instructions. The parser etc can be found in the UHC section. It makes
> use of the parser combinators found elsewhere in the tree,
>
> Doaitse Swierstra
>
> On woensdag, september 10, 2003, at 12:33 PM, Peter Robinson wrote:
> > Hello!
> > Does anyone know a reasonable standalone Parser for the Haskell
> > Grammar? The
> > only one i found was hsparser but it's still an alpha release and i
> > get a few
> > errors during compiling. I know i could write one using Happy but i
> > don't
> > want to reinvent the wheel...
> > regards
> > Peter
> >
> > _______________________________________________
> > Haskell-Cafe mailing list
> > Haskell-Cafe@haskell.org
> > http://www.haskell.org/mailman/listinfo/haskell-cafe
From doaitse@cs.uu.nl Wed Sep 10 13:56:14 2003
From: doaitse@cs.uu.nl (Doaitse Swierstra)
Date: Wed, 10 Sep 2003 14:56:14 +0200
Subject: Standalone Parser for Haskell Grammar
In-Reply-To: <200309101233.51274.listener@thaldyron.com>
Message-ID: <28D30BE0-E38E-11D7-85DB-000A95729144@cs.uu.nl>
You may find an error correcting combinator based parser in the
directory uust, to be found at cvs.cs.uu.nl
Just check out the whole tree and follow the building and installing
instructions. The parser etc can be found in the UHC section. It makes
use of the parser combinators found elsewhere in the tree,
Doaitse Swierstra
On woensdag, september 10, 2003, at 12:33 PM, Peter Robinson wrote:
> Hello!
> Does anyone know a reasonable standalone Parser for the Haskell
> Grammar? The
> only one i found was hsparser but it's still an alpha release and i
> get a few
> errors during compiling. I know i could write one using Happy but i
> don't
> want to reinvent the wheel...
> regards
> Peter
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
From kuq32tr02 at sneakemail.com Fri Sep 12 23:08:30 2003
From: kuq32tr02 at sneakemail.com (kuq32tr02@sneakemail.com)
Date: Fri Sep 12 18:08:33 2003
Subject: Simple IO Monad problem
Message-ID: <22197-22642@sneakemail.com>
Hello,
I'm starting to use Haskell for writing actual programs using monads and I'm already lost.
I have the following script:
#!/usr/bin/runhugs
> module Main where
> import System(getArgs)
> main = do putStr "Hello, World\n"
> strs <- getArgs
> map putStrLn strs
Which gives the following error:
runhugs: Error occurred
Reading file "./mailalias.lhs":
Reading file "/usr/lib/hugs/lib/System.hs":
Reading file "./mailalias.lhs":
Type checking
ERROR "./mailalias.lhs":5 - Type error in final generator
*** Term : map putStrLn strs
*** Type : [IO ()]
*** Does not match : IO a
Can someone please explain what I'm doing wrong?
Thanks!
From nick.name at inwind.it Sat Sep 13 01:25:39 2003
From: nick.name at inwind.it (Nick Name)
Date: Fri Sep 12 18:21:36 2003
Subject: Simple IO Monad problem
In-Reply-To: <22197-22642@sneakemail.com>
References: <22197-22642@sneakemail.com>
Message-ID: <200309130025.39933.nick.name@inwind.it>
Alle 00:08, sabato 13 settembre 2003, kuq32tr02@sneakemail.com ha
scritto:
> ERROR "./mailalias.lhs":5 - Type error in final generator
> *** Term ? ? ? ? ? : map putStrLn strs
> *** Type ? ? ? ? ? : [IO ()]
> *** Does not match : IO a
>
> Can someone please explain what I'm doing wrong?
This is a type error. You have to "mapM_", not map, see the types in the
documentation and try to convince yourself that you need an IO list and
not a list of IO, then that you really need an IO () and not an IO list
(wich would be returned by mapM). The syntax for a list of t in haskell
is [t], in case you didn't notice.
V.
From angagon at earthlink.net Fri Sep 12 17:27:59 2003
From: angagon at earthlink.net (Matt O'Connor)
Date: Fri Sep 12 18:24:37 2003
Subject: An IO Question from a Newbie
Message-ID: <200309121627.59788.angagon@earthlink.net>
Hello all. I'm new to functional programming and Haskell, but have been
programming in C and Java for a while. I've been going through the tutorials
and whatnot on haskell.org. I've read from the Gentle Introduction to
Haskell about IO and some of the other stuff and I have a question about it.
main = do putStr "Type Something: "
str <- getLine
putStrLn ("You typed: " ++ str)
When compile and run this code the "Type Something: " isn't displayed until
the putStrLn. So there is no prompt. The output looks like this.
s
Type Something: You typed: s
But if I change the putStr "Type Something: " to a putStrLn or put a \n at the
end of the string it displays the text immediately (ie, when I want it to).
Is there a good reason for this? Am I doing something wrong? Or do I need
to call some kind of standard output flush? Thanks.
Oh, I'm using ghc.
Matt
--
"Not everone knows Josiah Royce's definition of a liar as a man who
willfully misplaces his ontological predicates, but everyone who has
ever told a lie will recognize its accuracy."
Ch. 94: Truth -
"The Great Ideas: A Synopticon of Great Books of the Western World"
From ddarius at hotpop.com Fri Sep 12 19:25:07 2003
From: ddarius at hotpop.com (Derek Elkins)
Date: Fri Sep 12 18:27:34 2003
Subject: Simple IO Monad problem
In-Reply-To: <22197-22642@sneakemail.com>
References: <22197-22642@sneakemail.com>
Message-ID: <20030912182507.00001455.ddarius@hotpop.com>
On 12 Sep 2003 22:08:30 -0000
kuq32tr02@sneakemail.com wrote:
> Hello,
>
> I'm starting to use Haskell for writing actual programs using monads
> and I'm already lost.
>
> I have the following script:
>
> #!/usr/bin/runhugs
>
> > module Main where
> > import System(getArgs)
> > main = do putStr "Hello, World\n"
> > strs <- getArgs
> > map putStrLn strs
>
>
> Which gives the following error:
>
> runhugs: Error occurred
> Reading file "./mailalias.lhs":
> Reading file "/usr/lib/hugs/lib/System.hs":
> Reading file "./mailalias.lhs":
> Type checking
> ERROR "./mailalias.lhs":5 - Type error in final generator
> *** Term : map putStrLn strs
> *** Type : [IO ()]
> *** Does not match : IO a
>
> Can someone please explain what I'm doing wrong?
>
map :: (a -> b) -> [a] -> [b]
putStrLn :: String -> IO ()
therefore map putStrLn :: [String] -> [IO ()]
map maps a -pure function- over a list. What you want is to map a
-monadic computation- over the list, further you don't care about the
result.
mapM_ :: Monad m => (a -> m b) -> [a] -> m ()
mapM_ putStrLn :: [String] -> IO ()
From hdaume at ISI.EDU Fri Sep 12 17:18:22 2003
From: hdaume at ISI.EDU (Hal Daume III)
Date: Fri Sep 12 19:18:41 2003
Subject: An IO Question from a Newbie
In-Reply-To: <200309121627.59788.angagon@earthlink.net>
Message-ID:
This is a buffering problem. Use hSetBuffering to fix this (see Chapter 3
in YAHT -- www.isi.edu/~hdaume/htut/). Alternatively, use:
> main = do putStrLn "Type Something:"
> ...
in which case the "Ln" part will force it to be printed.
- Hal
On Fri, 12 Sep 2003, Matt O'Connor wrote:
> Hello all. I'm new to functional programming and Haskell, but have been
> programming in C and Java for a while. I've been going through the tutorials
> and whatnot on haskell.org. I've read from the Gentle Introduction to
> Haskell about IO and some of the other stuff and I have a question about it.
>
> main = do putStr "Type Something: "
> str <- getLine
> putStrLn ("You typed: " ++ str)
>
> When compile and run this code the "Type Something: " isn't displayed until
> the putStrLn. So there is no prompt. The output looks like this.
>
> s
> Type Something: You typed: s
>
> But if I change the putStr "Type Something: " to a putStrLn or put a \n at the
> end of the string it displays the text immediately (ie, when I want it to).
> Is there a good reason for this? Am I doing something wrong? Or do I need
> to call some kind of standard output flush? Thanks.
>
> Oh, I'm using ghc.
>
>
> Matt
>
>
--
Hal Daume III | hdaume@isi.edu
"Arrest this man, he talks in maths." | www.isi.edu/~hdaume
From ddarius at hotpop.com Fri Sep 12 20:17:05 2003
From: ddarius at hotpop.com (Derek Elkins)
Date: Fri Sep 12 19:19:17 2003
Subject: An IO Question from a Newbie
In-Reply-To: <200309121627.59788.angagon@earthlink.net>
References: <200309121627.59788.angagon@earthlink.net>
Message-ID: <20030912191705.0000677a.ddarius@hotpop.com>
On Fri, 12 Sep 2003 16:27:59 -0600
Matt O'Connor wrote:
> Hello all. I'm new to functional programming and Haskell, but have
> been programming in C and Java for a while. I've been going through
> the tutorials and whatnot on haskell.org. I've read from the Gentle
> Introduction to Haskell about IO and some of the other stuff and I
> have a question about it.
>
> main = do putStr "Type Something: "
> str <- getLine
> putStrLn ("You typed: " ++ str)
>
> When compile and run this code the "Type Something: " isn't displayed
> until the putStrLn. So there is no prompt. The output looks like
> this.
>
> s
> Type Something: You typed: s
>
> But if I change the putStr "Type Something: " to a putStrLn or put a
> \n at the end of the string it displays the text immediately (ie, when
> I want it to). Is there a good reason for this? Am I doing something
> wrong? Or do I need to call some kind of standard output flush?
Yes, the problem is that the first line is not being flushed. Importing
hFlush and stdout from IO (or System.IO) and adding hFlush stdout after
you putStr will fix it. Alternatively, you could change the buffering
on stdout to NoBuffering. I don't know if there is a standard
putStrWithFlush function or just a better answer than this. A
putStrWithFlush would be trivial to write or more generally to a
HOF that flushed after performing the action passed to it.
From glynn.clements at virgin.net Sat Sep 13 01:42:41 2003
From: glynn.clements at virgin.net (Glynn Clements)
Date: Fri Sep 12 19:43:04 2003
Subject: An IO Question from a Newbie
In-Reply-To: <200309121627.59788.angagon@earthlink.net>
References: <200309121627.59788.angagon@earthlink.net>
Message-ID: <16226.23025.91228.835965@cerise.nosuchdomain.co.uk>
Matt O'Connor wrote:
> Hello all. I'm new to functional programming and Haskell, but have been
> programming in C and Java for a while. I've been going through the tutorials
> and whatnot on haskell.org. I've read from the Gentle Introduction to
> Haskell about IO and some of the other stuff and I have a question about it.
>
> main = do putStr "Type Something: "
> str <- getLine
> putStrLn ("You typed: " ++ str)
>
> When compile and run this code the "Type Something: " isn't displayed until
> the putStrLn. So there is no prompt. The output looks like this.
>
> s
> Type Something: You typed: s
>
> But if I change the putStr "Type Something: " to a putStrLn or put a \n at the
> end of the string it displays the text immediately (ie, when I want it to).
> Is there a good reason for this? Am I doing something wrong? Or do I need
> to call some kind of standard output flush? Thanks.
Yes; if you don't want a newline after the prompt, you need to use:
hFlush stdout
to flush the stream.
--
Glynn Clements
From brandon at its.caltech.edu Sun Sep 14 01:23:39 2003
From: brandon at its.caltech.edu (Brandon Michael Moore)
Date: Sun Sep 14 03:23:46 2003
Subject: An IO Question from a Newbie
In-Reply-To:
References:
Message-ID:
Hal was pretty terse, so I'll explain why switching to putStrLn will help.
stdout is line buffered.
At least by default (see hSetBuffering). That means output will only be
flushed to the screen once a newline is written. Your prompt wasn't
printed because it didn't have a newline, so it was buffered until the
second print provided one (read from the user, by way of s).
This is hardly specific to Haskell. Try this C program:
#import
#import
int main(int a,char** b) {
fputs("test",stdout);
sleep(1);
fputs("boo!\n",stdout);
return 0;
}
on my system this sleeps a second then prints "testboo!". I used fputs
rather than puts becuase puts appends a newline and fputs doesn't.
Similarly, putStrLn appends a newline and putStr doesn't.
This change does mean input will be entered on the next line, rather then
on the same line as the prompt. This should be acceptable. If you really
need to have a prompt at the start of the line then consider hFlush or
hSetBuffering.
Every time I've seen this question asked people post responses that only
mention hFlush, implying you need it to display output when you want it.
Please don't give newbies the impression you need hFlush for basic IO.
Monadic IO is scary enough to begin with.
This seems to be a common problem so I added some comments about it on the
Wiki, under UsingIO in the FrequentlyAskedQuestions.
Brandon
On Fri, 12 Sep 2003, Hal Daume III wrote:
> This is a buffering problem. Use hSetBuffering to fix this (see Chapter 3
> in YAHT -- www.isi.edu/~hdaume/htut/). Alternatively, use:
>
> > main = do putStrLn "Type Something:"
> > ...
>
>
> in which case the "Ln" part will force it to be printed.
>
> - Hal
>
> On Fri, 12 Sep 2003, Matt O'Connor wrote:
>
> > Hello all. I'm new to functional programming and Haskell, but have been
> > programming in C and Java for a while. I've been going through the tutorials
> > and whatnot on haskell.org. I've read from the Gentle Introduction to
> > Haskell about IO and some of the other stuff and I have a question about it.
> >
> > main = do putStr "Type Something: "
> > str <- getLine
> > putStrLn ("You typed: " ++ str)
> >
> > When compile and run this code the "Type Something: " isn't displayed until
> > the putStrLn. So there is no prompt. The output looks like this.
> >
> > s
> > Type Something: You typed: s
> >
> > But if I change the putStr "Type Something: " to a putStrLn or put a \n at the
> > end of the string it displays the text immediately (ie, when I want it to).
> > Is there a good reason for this? Am I doing something wrong? Or do I need
> > to call some kind of standard output flush? Thanks.
> >
> > Oh, I'm using ghc.
> >
> >
> > Matt
> >
> >
>
> --
> Hal Daume III | hdaume@isi.edu
> "Arrest this man, he talks in maths." | www.isi.edu/~hdaume
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
>
From qrczak at knm.org.pl Sun Sep 14 12:10:58 2003
From: qrczak at knm.org.pl (Marcin 'Qrczak' Kowalczyk)
Date: Sun Sep 14 05:11:01 2003
Subject: No safety in numbers
In-Reply-To: <200308212230.33161.hinsen@cnrs-orleans.fr>
References: <200308212230.33161.hinsen@cnrs-orleans.fr>
Message-ID: <200309141110.58099.qrczak@knm.org.pl>
Dnia czw 21. sierpnia 2003 22:30, Konrad Hinsen napisa?:
> k_B = 0.0083144708636327096
>
> The trouble is that k_B then becomes "Double" by default (or any other
> type I declare it to be).
Declare it as
k_B :: Fractional a => a
Performance may suffer even in GHC if optimization is turned off.
BTW, Hugs incorrectly converts such numbers through Double which it
represents as C float.
--
__("< Marcin Kowalczyk
\__/ qrczak@knm.org.pl
^^ http://qrnik.knm.org.pl/~qrczak/
From mark at felinemail.zzn.com Sun Sep 14 10:40:51 2003
From: mark at felinemail.zzn.com (Mark Espinoza)
Date: Sun Sep 14 10:28:18 2003
Subject: YAHT Problem
Message-ID: <33B50AEEEAD0E4040B5E8D635DE618A6@mark.felinemail.zzn.com>
An HTML attachment was scrubbed...
URL: http://porky.devel.redhat.com/pipermail/haskell-cafe/attachments/20030914/e79f9725/attachment.htm
From glynn.clements at virgin.net Sun Sep 14 17:09:37 2003
From: glynn.clements at virgin.net (Glynn Clements)
Date: Sun Sep 14 11:42:59 2003
Subject: An IO Question from a Newbie
In-Reply-To:
References:
Message-ID: <16228.33969.14389.53704@cerise.nosuchdomain.co.uk>
Brandon Michael Moore wrote:
> Hal was pretty terse, so I'll explain why switching to putStrLn will help.
>
> stdout is line buffered.
>
> At least by default (see hSetBuffering). That means output will only be
> flushed to the screen once a newline is written. Your prompt wasn't
> printed because it didn't have a newline, so it was buffered until the
> second print provided one (read from the user, by way of s).
>
> This is hardly specific to Haskell. Try this C program:
But there's one significant difference between C and Haskell, which is
applicable in the case of Matt's program. In C, any line-buffered
output streams are automatically flushed when a read from an
unbuffered or line-buffered stream can't be satisfied from its buffer.
Also, it seemed fairly clear from Matt's original message that:
a) he didn't want to have to force a new-line (he noted that doing so
eliminated the problem), and
b) he understood the concept of flushing, but presumably didn't know
how to do it in Haskell.
While we're on the subject, I'll point out a couple of other
differences between the buffering in ANSI C's stdio library and
Haskell's:
1. In Haskell, you can change the buffering mode at any point; in C,
you have to change it before any data is read from or written to the
stream, otherwise the behaviour is undefined.
2. For an input stream which is associated with a tty, changing the
buffering mode may also change the terminal settings (setting it to
unbuffered disables canonical mode while setting it to line-buffered
or fully-buffered enables it).
--
Glynn Clements
From brandon at its.caltech.edu Sun Sep 14 15:11:15 2003
From: brandon at its.caltech.edu (Brandon Michael Moore)
Date: Sun Sep 14 17:11:19 2003
Subject: An IO Question from a Newbie
In-Reply-To: <16228.33969.14389.53704@cerise.nosuchdomain.co.uk>
References:
<16228.33969.14389.53704@cerise.nosuchdomain.co.uk>
Message-ID:
On Sun, 14 Sep 2003, Glynn Clements wrote:
>
> Brandon Michael Moore wrote:
>
> > Hal was pretty terse, so I'll explain why switching to putStrLn will help.
> >
> > stdout is line buffered.
> >
> > At least by default (see hSetBuffering). That means output will only be
> > flushed to the screen once a newline is written. Your prompt wasn't
> > printed because it didn't have a newline, so it was buffered until the
> > second print provided one (read from the user, by way of s).
> >
> > This is hardly specific to Haskell. Try this C program:
>
> But there's one significant difference between C and Haskell, which is
> applicable in the case of Matt's program. In C, any line-buffered
> output streams are automatically flushed when a read from an
> unbuffered or line-buffered stream can't be satisfied from its buffer.
Interesting. I didn't know this. Maybe we should match this behaviour, or
provide a write-string-and-flush function. It seems like this issue
is causing an undue amound of trouble.
> Also, it seemed fairly clear from Matt's original message that:
>
> a) he didn't want to have to force a new-line (he noted that doing so
> eliminated the problem), and
I should note here that there is a gnu readline binding distributed with
GHC. It's undocumented, but it seems to follow the C API pretty closely,
and you can make a decent interface using only two of the functions.
> b) he understood the concept of flushing, but presumably didn't know
> how to do it in Haskell.
>
> While we're on the subject, I'll point out a couple of other
> differences between the buffering in ANSI C's stdio library and
> Haskell's:
>
> 1. In Haskell, you can change the buffering mode at any point; in C,
> you have to change it before any data is read from or written to the
> stream, otherwise the behaviour is undefined.
>
> 2. For an input stream which is associated with a tty, changing the
> buffering mode may also change the terminal settings (setting it to
> unbuffered disables canonical mode while setting it to line-buffered
> or fully-buffered enables it).
>
> --
> Glynn Clements
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
>
From droundy at abridgegame.org Sun Sep 14 19:52:59 2003
From: droundy at abridgegame.org (David Roundy)
Date: Sun Sep 14 18:53:00 2003
Subject: zlib binding providing Handle to compressed file.
Message-ID: <20030914225256.GA27346@jdj5.mit.edu>
I've just created a binding to the gzopen function of zlib which causes it
to create a Handle. The code currently only supports ReadMode and
WriteMode, and hFileSize won't work properly when reading a file. In fact,
pretty much nothing but plain old reading and writing will work, but such
is life.
Anyhow in case anyone is interested, I'm attaching the code. It creates a
pipe using pipe(2) and spawns a thread to pass the data between the pipe
and gzread or gzwrite. It's not pretty, but it's better than any other
solution I could think of. Suggestions or criticisms are welcome.
--
David Roundy
http://www.abridgegame.org/darcs
-------------- next part --------------
\begin{code}
module Zlib ( gzOpenFile, gzWriteFile, gzReadFile ) where
import IO
import System.IO ( hGetBuf, hPutBuf )
import Control.Concurrent ( forkIO )
import Monad ( when )
import Foreign.C.String ( CString, withCString )
import Foreign.Marshal.Array ( mallocArray, withArray, peekArray )
import Foreign.Marshal.Alloc ( free )
import Foreign.Ptr ( Ptr )
import Data.Word
import GHC.Handle ( openFd )
fdToReadHandle fd fn = openFd fd Nothing fn ReadMode False False
fdToWriteHandle fd fn = openFd fd Nothing fn WriteMode False False
gzOpenFile :: FilePath -> IOMode -> IO Handle
gzWriteFile :: FilePath -> String -> IO ()
gzOpenFile f ReadMode =
withCString f $ \fstr -> withCString "rb" $ \rb-> do
gzf <- c_gzopen fstr rb
withArray [0,0] $ \fds -> do
err <- c_pipe fds
when (err /= 0) $ error "Pipe problem!"
[infd,outfd] <- peekArray 2 fds
writeH <- fdToWriteHandle (fromIntegral outfd) f
buf <- mallocArray 1024
forkIO $ gzreader gzf writeH buf
fdToReadHandle (fromIntegral infd) f
where gzreader gzf h buf =
do done <- hIsClosed h
if done
then do c_gzclose gzf
free buf
hClose h
else do l <- c_gzread gzf buf 1024
hPutBuf h buf l
if l < 1024
then do free buf
c_gzclose gzf
hClose h
else gzreader gzf h buf
gzOpenFile f WriteMode =
withCString f $ \fstr -> withCString "wb" $ \wb-> do
gzf <- c_gzopen fstr wb
withArray [0,0] $ \fds -> do
err <- c_pipe fds
when (err /= 0) $ error "Pipe problem!"
[infd,outfd] <- peekArray 2 fds
readH <- fdToReadHandle (fromIntegral infd) f
buf <- mallocArray 1024
forkIO $ gzwriter gzf readH buf
fdToWriteHandle (fromIntegral outfd) f
where gzwriter gzf h buf =
do done <- hIsEOF h
if done
then do c_gzclose gzf
free buf
hClose h
else do l <- hGetBuf h buf 1024
c_gzwrite gzf buf l
gzwriter gzf h buf
gzWriteFile f s = do h <- gzOpenFile f WriteMode
hPutStr h s
hClose h
gzReadFile f s = do h <- gzOpenFile f WriteMode
hGetContents h
foreign import ccall unsafe "static unistd.h pipe" c_pipe
:: Ptr Int -> IO Int
foreign import ccall unsafe "static unistd.h read" c_read
:: Ptr Word8 -> Int -> IO Int
foreign import ccall unsafe "static zlib.h gzopen" c_gzopen
:: CString -> CString -> IO (Ptr ())
foreign import ccall unsafe "static zlib.h gzclose" c_gzclose
:: Ptr () -> IO ()
foreign import ccall unsafe "static zlib.h gzread" c_gzread
:: Ptr () -> Ptr Word8 -> Int -> IO Int
foreign import ccall unsafe "static zlib.h gzwrite" c_gzwrite
:: Ptr () -> Ptr Word8 -> Int -> IO ()
\end{code}
From stein at eecs.harvard.edu Mon Sep 15 01:48:29 2003
From: stein at eecs.harvard.edu (Lex Stein)
Date: Mon Sep 15 00:48:30 2003
Subject: threaded red-black tree
Message-ID:
Hi, No one responded to my question several weeks ago about a purely
functional implementation of a threaded, red-black tree. My message was
sent about the same time as that flurry of silly emails about "how to
respond to homework questions". Was my message not responded to because it
was classified as a homework question? I assure you this is officework,
not homework. I ended up porting Okasaki's red-black tree implementation;
hacking it apart with a bunch of mutation for the threading of the list
through the tree. However, I'm still missing a deletion function and I
haven't been able to find a prototype (Okasaki's red-black tree module
lacks delete). My study of the RB-tree deletion routine in CLR hasn't yet
yielded an adaptation for a functional environment. Any advice would be
much appreciated.
Thanks,
Lex
--
Lex Stein http://www.eecs.harvard.edu/~stein/
stein@eecs.harvard.edu cell: 617-233-0246
From cwitty at newtonlabs.com Sun Sep 14 23:44:56 2003
From: cwitty at newtonlabs.com (Carl Witty)
Date: Mon Sep 15 01:53:29 2003
Subject: threaded red-black tree
In-Reply-To:
References:
Message-ID: <1063604695.994.55.camel@flare>
On Sun, 2003-09-14 at 21:48, Lex Stein wrote:
> Hi, No one responded to my question several weeks ago about a purely
> functional implementation of a threaded, red-black tree.
I'm not sure what you mean by "threaded". By simply ignoring that word,
I come up with the following solution :-)
There is a purely functional implementation of a red-black tree in the
MetaPRL system (www.metaprl.org), written in OCaml. For the latest CVS
version of this red-black tree code, go to
http://cvs.metaprl.org:12000/cvsweb/metaprl/libmojave/stdlib/ (look at
lm_map.ml and lm_set.ml).
Carl Witty
From nick.name at inwind.it Mon Sep 15 15:38:38 2003
From: nick.name at inwind.it (Nick Name)
Date: Mon Sep 15 08:34:42 2003
Subject: Instance checking and phantom types
Message-ID: <200309151438.38891.nick.name@inwind.it>
Hi all, I have an example wich I don't understand:
---------------begin
class C t
data T = T
instance C T
data C t => T1 t = T1
f1 :: T1 ()
f1 = T1
data C t => T2 t = T2 t
f2 :: T2 ()
f2 = T2 ()
----------------end
The first function, f1, is accepted both by hugs and ghc, unlike the
second wich is rejected.
Why does this happen? Shouldn't f1 be rejected with "no instance C ()"
Thanks for help
Vincenzo
From andrew at acooke.org Mon Sep 15 09:57:58 2003
From: andrew at acooke.org (andrew cooke)
Date: Mon Sep 15 08:58:05 2003
Subject: threaded red-black tree
In-Reply-To:
References:
Message-ID: <33731.139.229.3.218.1063630678.squirrel@127.0.0.1>
this might help:
http://www.cs.kent.ac.uk/people/staff/smk/redblack/Untyped.hs
andrew
Lex Stein said:
>
> Hi, No one responded to my question several weeks ago about a purely
> functional implementation of a threaded, red-black tree. My message was
> sent about the same time as that flurry of silly emails about "how to
> respond to homework questions". Was my message not responded to because it
> was classified as a homework question? I assure you this is officework,
> not homework. I ended up porting Okasaki's red-black tree implementation;
> hacking it apart with a bunch of mutation for the threading of the list
> through the tree. However, I'm still missing a deletion function and I
> haven't been able to find a prototype (Okasaki's red-black tree module
> lacks delete). My study of the RB-tree deletion routine in CLR hasn't yet
> yielded an adaptation for a functional environment. Any advice would be
> much appreciated.
>
> Thanks,
> Lex
>
> --
> Lex Stein http://www.eecs.harvard.edu/~stein/
> stein@eecs.harvard.edu cell: 617-233-0246
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
>
--
http://www.acooke.org/andrew
From belloc_f at epita.fr Mon Sep 15 16:55:29 2003
From: belloc_f at epita.fr (Frederic BELLOC)
Date: Mon Sep 15 09:55:35 2003
Subject: Read file problems
Message-ID:
HI,
I have a recurrent probleme with function readFile and Monad :
it is that i try to get a line, transform it and stock it in a list
and what i want is that function return me the list.
But hugs say me that in
readFile my_file >>= \s -> map cons_line (lines s)
readFile is a IO String type but is used here as [[Char]] type...
and i don't know what to do...
Ghc say me that is the lambda abstraction that fails with
"map cons_line (lines s)" , he couldn't match IO against [] !
Help me please, i understand well (i hope) how Monad work but here i don't see
a solution.
Sorry for my poor english but i'm already a student.
Thanks for all.
--
C, socks and sun ;-)
and haskell bugs :-(
From hdaume at ISI.EDU Mon Sep 15 08:19:28 2003
From: hdaume at ISI.EDU (Hal Daume III)
Date: Mon Sep 15 10:20:22 2003
Subject: Read file problems
In-Reply-To:
References:
Message-ID: <1063635568.26187.16.camel@hal>
Hi,
This is a pretty simple problem to fix. (>>=) has type IO a -> (a -> IO
b) -> IO b. 'readFile my_file' has type IO String, so this means
whatever comes on the RHS of >>= should have type (String -> IO b). In
your case, it doesn't. It has type String -> [something], but the
[something] isn't an IO type.
Hint: you need to put a call to 'return' in there.
- Hal
On Mon, 2003-09-15 at 06:55, Frederic BELLOC wrote:
> HI,
> I have a recurrent probleme with function readFile and Monad :
> it is that i try to get a line, transform it and stock it in a list
> and what i want is that function return me the list.
> But hugs say me that in
>
> readFile my_file >>= \s -> map cons_line (lines s)
> readFile is a IO String type but is used here as [[Char]] type...
> and i don't know what to do...
>
> Ghc say me that is the lambda abstraction that fails with
> "map cons_line (lines s)" , he couldn't match IO against [] !
>
> Help me please, i understand well (i hope) how Monad work but here i don't see
> a solution.
>
> Sorry for my poor english but i'm already a student.
>
> Thanks for all.
--
--
Hal Daume III | hdaume@isi.edu
"Arrest this man, he talks in maths." | www.isi.edu/~hdaume
From belloc_f at epita.fr Mon Sep 15 17:27:58 2003
From: belloc_f at epita.fr (Frederic BELLOC)
Date: Mon Sep 15 10:28:02 2003
Subject: Read file problems
In-Reply-To: <1063635568.26187.16.camel@hal> (Hal Daume, III's message of
"15 Sep 2003 07:19:28 -0700")
References: <1063635568.26187.16.camel@hal>
Message-ID:
Hal Daume III disait r?cemment :
> Hi,
>
> This is a pretty simple problem to fix. (>>=) has type IO a -> (a -> IO
> b) -> IO b. 'readFile my_file' has type IO String, so this means
> whatever comes on the RHS of >>= should have type (String -> IO b). In
> your case, it doesn't. It has type String -> [something], but the
> [something] isn't an IO type.
>
> Hint: you need to put a call to 'return' in there.
>
Yes, thanks
ps : i've read something like that in the Monad Tutorial but i was not
sure...
http://www.nomaware.com/monads/html/index.html
--
C, socks and sun ;-)
No haskell bug :-D
From simonmar at microsoft.com Mon Sep 15 17:11:56 2003
From: simonmar at microsoft.com (Simon Marlow)
Date: Mon Sep 15 11:12:07 2003
Subject: An IO Question from a Newbie
Message-ID: <3429668D0E777A499EE74A7952C382D1CF693D@EUR-MSG-01.europe.corp.microsoft.com>
> > But there's one significant difference between C and
> Haskell, which is
> > applicable in the case of Matt's program. In C, any line-buffered
> > output streams are automatically flushed when a read from an
> > unbuffered or line-buffered stream can't be satisfied from
> its buffer.
>
> Interesting. I didn't know this. Maybe we should match this
> behaviour, or
> provide a write-string-and-flush function. It seems like this issue
> is causing an undue amound of trouble.
I wrote GHC's IO library, and deliberately didn't include this feature.
The previous version of the library did have such a feature,
specifically for stdin/stdout. Note that the report doesn't say we must
do this.
The reason I didn't include the feature is because I can't see a way to
do it right. Flushing *all* line-buffered handles (the ANSI C way)
doesn't seem right. Flushing stdout just because we read from stdin is
not right, because the two streams might refer to completely different
I/O objects. Perhaps we should attempt to detect when there are two
streams connected to the same I/O object (file, pipe, tty, whatever) and
enable the magic flushing then. But now do I have to explain to people
how this works?
I suppose we could take the view that extra flushing is basically
harmless, so it doesn't matter that we flush a bunch of Handles more
often than we need to.
The advantage of the current scheme is that it is easy to understand and
explain; the library doesn't try to do clever stuff behind your back.
The disadvantage is that it catches people out, and it sometimes
requires you to import IO in an otherwise Prelude-only program.
I'm more-or-less agnostic - if there's a way to avoid catching people
out without introducing too much overhead or complicated rules that we
have to explain, then I'll happily implement it.
Cheers,
Simon
From Sven.Panne at informatik.uni-muenchen.de Mon Sep 15 21:07:45 2003
From: Sven.Panne at informatik.uni-muenchen.de (Sven Panne)
Date: Mon Sep 15 14:08:28 2003
Subject: Instance checking and phantom types
In-Reply-To: <200309151438.38891.nick.name@inwind.it>
References: <200309151438.38891.nick.name@inwind.it>
Message-ID: <3F65FFF1.7000101@informatik.uni-muenchen.de>
Nick Name wrote:
> Hi all, I have an example wich I don't understand:
First of all, let's rename the constructors and types a bit to make
things clearer add the instance in question, and remove the type
signatures:
----------------------------------------------------------------
module Main where
class C t
data T = MkT
instance C T
instance C ()
data C t => T1 t = MkT1
f1 = MkT1
data C t => T2 t = MkT2 t
f2 = MkT2 ()
----------------------------------------------------------------
Then we can easily ask GHC:
----------------------------------------------------------------
panne@jeanluc:~> ghci -v0 Main.hs
*Main> :i T1 MkT1 f1 T2 MkT2 f2
-- T1 is a type constructor, defined at Main.hs:8
data (C t) => T1 t = MkT1
-- MkT1 is a data constructor, defined at Main.hs:8
MkT1 :: forall t. T1 t
-- f1 is a variable, defined at Main.hs:10
f1 :: forall t. T1 t
-- T2 is a type constructor, defined at Main.hs:12
data (C t) => T2 t = MkT2 t
-- MkT2 is a data constructor, defined at Main.hs:12
MkT2 :: forall t. (C t) => t -> T2 t
-- f2 is a variable, defined at Main.hs:14
f2 :: T2 ()
----------------------------------------------------------------
> The first function, f1, is accepted both by hugs and ghc, unlike the
> second wich is rejected.
>
> Why does this happen? Shouldn't f1 be rejected with "no instance C ()"
The reason is buried in
http://haskell.org/onlinereport/decls.html#sect4.2.1
In a nutshell: The context in datatype declarations has only an effect for
the *data* constructors of that type which use the type variables mentioned
in the context. Contexts have no effect for the *type* constructor. IIRC the
reason for this design decision was that contexts in type signatures should
always be explicit.
Cheers,
S.
From nick.name at inwind.it Mon Sep 15 21:44:21 2003
From: nick.name at inwind.it (Nick Name)
Date: Mon Sep 15 14:40:14 2003
Subject: Instance checking and phantom types
In-Reply-To: <3F65FFF1.7000101@informatik.uni-muenchen.de>
References: <200309151438.38891.nick.name@inwind.it>
<3F65FFF1.7000101@informatik.uni-muenchen.de>
Message-ID: <200309152044.21533.nick.name@inwind.it>
Alle 20:07, luned? 15 settembre 2003, Sven Panne ha scritto:
> IIRC the
> reason for this design decision was that contexts in type signatures
> should always be explicit.
Got it ;) Thanks for prompt reply. What does "should always be explicit"
mean? Is there a notion of "explicit context" that I should know?
Thanks
Vincenzo
From heringto at cs.unc.edu Mon Sep 15 15:50:13 2003
From: heringto at cs.unc.edu (Dean Herington)
Date: Mon Sep 15 14:50:16 2003
Subject: simpler I/O buffering [was: RE: An IO Question from a Newbie]
In-Reply-To: <3429668D0E777A499EE74A7952C382D1CF693D@EUR-MSG-01.europe.corp.microsoft.com>
Message-ID:
I've long thought that I/O buffering behavior--not just in Haskell, but
in most places I've encountered it--was unnecessarily complicated.
Perhaps it could be simplified dramatically by treating it as strictly a
performance optimization. Here's a sketch of the approach.
Writing a sequence of characters across the interface I'm proposing is a
request by the writing program for those characters to appear at their
destination "soon". Ideally, "soon" would be "immediately"; however, the
characters' appearance may deliberately be delayed ("buffered"), for
efficiency, as long as such delay is "unobtrusive" to a human user of the
program. Buffering timeouts would depend on the device; for a terminal,
perhaps 50-100 ms would be appropriate. Such an interval would tend not
to be noticeable to a human user but would be long enough to effectively
collect, say, an entire line of output for output "in one piece". The use
of a reasonable timeout would avoid the confusing behavior where a
newline-less prompt doesn't appear until the prompted data is entered.
With this scheme, I/O buffering no longer has any real semantic content.
(In particular, the interface never guarantees indefinite delay in
outputting written characters. Line buffering, if semantically important,
needs to be done above the level of this interface.) Hence, buffering
control could be completely eliminated from the interface. However, I
would retain it to provide (non-semantic) control over buffering. The
optional buffer size currently has such an effect. A timeout value could
be added for fine tuning. (Note that a timeout of zero would have an
effect similar to Haskell's current NoBuffering.) Lastly, the "flush"
operation would remain, as a hint that it's not worth waiting even the
limited timeout period before endeavoring to make the characters appear.
Is such an approach feasible? Has it been implemented anywhere? Would
such behavior best be implemented by the operating system? Could it be
implemented by the runtime system?
Dean
From Sven.Panne at informatik.uni-muenchen.de Mon Sep 15 22:04:41 2003
From: Sven.Panne at informatik.uni-muenchen.de (Sven Panne)
Date: Mon Sep 15 15:05:25 2003
Subject: Instance checking and phantom types
In-Reply-To: <200309152044.21533.nick.name@inwind.it>
References: <200309151438.38891.nick.name@inwind.it>
<3F65FFF1.7000101@informatik.uni-muenchen.de>
<200309152044.21533.nick.name@inwind.it>
Message-ID: <3F660D49.30104@informatik.uni-muenchen.de>
Nick Name wrote:
> Got it ;) Thanks for prompt reply. What does "should always be explicit"
> mean? Is there a notion of "explicit context" that I should know?
What I meant was the fact that you always have to write down *all* contexts
involved in a type signature. Nothing is "inherited under the hood" by
contexts in datatype declarations.
Cheers,
S.
From Tom.Pledger at peace.com Tue Sep 16 09:36:52 2003
From: Tom.Pledger at peace.com (Tom Pledger)
Date: Mon Sep 15 16:37:06 2003
Subject: threaded red-black tree
In-Reply-To: <1063604695.994.55.camel@flare>
References:
<1063604695.994.55.camel@flare>
Message-ID: <16230.8932.253663.5756@tux-17.corp.peace.com>
Carl Witty writes:
| On Sun, 2003-09-14 at 21:48, Lex Stein wrote:
| > Hi, No one responded to my question several weeks ago about a purely
| > functional implementation of a threaded, red-black tree.
|
| I'm not sure what you mean by "threaded". By simply ignoring that word,
| I come up with the following solution :-)
IIRC a threaded tree (in an imperative language) is one where 'unused'
child pointers are made to point to the next (right child pointer) or
previous (left child pointer) node in an in-order traversal. The
pointers have to be flagged to show whether they're normal or
threading.
For example, if this tree
R
/ \
L S
\
M
were threaded, the unused pointers would be pressed into service thus:
L's left: still nil, because L is the least element
M's left: thread to L (predecessor)
M's right: thread to R (successor)
S's left: thread to R (predecessor)
S's right: still nil, because S is the greatest element
A benefit of threading is that you can make an in-order traversal in
constant space, because you don't have to remember the whole path from
the root to your current position.
You *could* translate it into a purely functional representation,
along these lines
data TRBT a = Empty | Node Colour (Ptr a) a (Ptr a)
data Colour = Red | Black
data Ptr a = Child (TRBT a) | Thread (TRBT a)
but you'd have to do some tricky stuff
http://haskell.org/hawiki/TyingTheKnot
to deal with the circular nature of the data structure (e.g. in the
above tree, R points to L, L points to M, and M points to R). Also
note that every insert or delete is O(n) instead of O(log n), because
*every* node in the old tree can see the part you change.
I suggest you (Lex) either go imperative (with STRef or IORef) or do
without threading, unless you're sure that you'll be doing many more
lookups and traversals than inserts and deletes.
Regards,
Tom
From glynn.clements at virgin.net Tue Sep 16 03:04:01 2003
From: glynn.clements at virgin.net (Glynn Clements)
Date: Mon Sep 15 21:04:27 2003
Subject: simpler I/O buffering [was: RE: An IO Question from a Newbie]
In-Reply-To:
References: <3429668D0E777A499EE74A7952C382D1CF693D@EUR-MSG-01.europe.corp.microsoft.com>
Message-ID: <16230.24961.810923.837752@cerise.nosuchdomain.co.uk>
Dean Herington wrote:
> I've long thought that I/O buffering behavior--not just in Haskell, but
> in most places I've encountered it--was unnecessarily complicated.
> Perhaps it could be simplified dramatically by treating it as strictly a
> performance optimization.
This isn't entirely possible; there will always be situations where it
matters as to exactly when and how the data gets passed to the OS. My
experience taught me that the simplest solution was never to use ANSI
stdio buffering in such situations.
> Here's a sketch of the approach.
>
> Writing a sequence of characters across the interface I'm proposing is a
> request by the writing program for those characters to appear at their
> destination "soon". Ideally, "soon" would be "immediately"; however, the
> characters' appearance may deliberately be delayed ("buffered"), for
> efficiency, as long as such delay is "unobtrusive" to a human user of the
> program. Buffering timeouts would depend on the device; for a terminal,
> perhaps 50-100 ms would be appropriate. Such an interval would tend not
> to be noticeable to a human user but would be long enough to effectively
> collect, say, an entire line of output for output "in one piece". The use
> of a reasonable timeout would avoid the confusing behavior where a
> newline-less prompt doesn't appear until the prompted data is entered.
>
> With this scheme, I/O buffering no longer has any real semantic content.
> (In particular, the interface never guarantees indefinite delay in
> outputting written characters. Line buffering, if semantically important,
> needs to be done above the level of this interface.)
That's already true, at least in C: if you output a line which is
longer than the buffer, the buffer will be flushed before it contains
a newline (i.e. the line won't be written atomically).
> Hence, buffering
> control could be completely eliminated from the interface. However, I
> would retain it to provide (non-semantic) control over buffering. The
> optional buffer size currently has such an effect. A timeout value could
> be added for fine tuning. (Note that a timeout of zero would have an
> effect similar to Haskell's current NoBuffering.) Lastly, the "flush"
> operation would remain, as a hint that it's not worth waiting even the
> limited timeout period before endeavoring to make the characters appear.
>
> Is such an approach feasible?
Possibly.
As things stand, anyone who writes code which relies upon output being
held back until a flush is asking for trouble. So, your approach
wouldn't make it any harder to write correct code, although it might
make it significantly more obvious if code was incorrect.
AFAICT, the biggest problem would be providing an upper bound on the
delay, as that implies some form of preemptive concurrency.
> Has it been implemented anywhere?
Not that I know of.
> Would such behavior best be implemented by the operating system?
No. The OS (i.e. kernel) doesn't know anything about user-space
buffering. Furthermore, one of the main functions of user-space
buffering is to minimise the number of system calls, so putting it
into the OS would be pointless.
> Could it be implemented by the runtime system?
It depends what you mean by "the runtime system"; it would have to be
implemented in user-space.
--
Glynn Clements
From simons at cryp.to Tue Sep 16 14:37:48 2003
From: simons at cryp.to (Peter Simons)
Date: Tue Sep 16 07:37:51 2003
Subject: Fast I/O with sockets
Message-ID: <87oexl6k1f.fsf@peti.cryp.to>
Hi,
I was wondering how to read and write from a Socket in the most
performant way. According to the library documentation from GHC,
'hGetBuf' and 'hPutBuf' are the way to go. But my problem with these
functions is that they expect to read exactly the number of bytes I
gave them!
The IO computation
hGetBuf sock ptr 1024
wants to read 1024 bytes, no less. This doesn't work for me, because I
need to drive an interactive line-based protocol session. I need the
read operation to consume as much data as is available and then to
return immediately, so that I can process the command right away.
As an alternative, I looked at 'hGetLine', but this doesn't work for
me either, at least not very well, because in my protocol, lines are
terminated by "\r\n" -- not just "\n", like hGetLine expects it.
Finally, I considered 'hGetContents', which has the nice property of
returning a lazy-evaluated list of the data read from the socket. But
unfortunately, I don't see how I could implement something like a
"read timeout" on the socket when using this function.
Any ideas, anybody?
Peter
From simonmar at microsoft.com Tue Sep 16 14:45:47 2003
From: simonmar at microsoft.com (Simon Marlow)
Date: Tue Sep 16 08:45:52 2003
Subject: Fast I/O with sockets
Message-ID: <3429668D0E777A499EE74A7952C382D1D8471D@EUR-MSG-01.europe.corp.microsoft.com>
> I was wondering how to read and write from a Socket in the most
> performant way. According to the library documentation from GHC,
> 'hGetBuf' and 'hPutBuf' are the way to go. But my problem with these
> functions is that they expect to read exactly the number of bytes I
> gave them!
>
> The IO computation
>
> hGetBuf sock ptr 1024
>
> wants to read 1024 bytes, no less. This doesn't work for me, because I
> need to drive an interactive line-based protocol session. I need the
> read operation to consume as much data as is available and then to
> return immediately, so that I can process the command right away.
>
> As an alternative, I looked at 'hGetLine', but this doesn't work for
> me either, at least not very well, because in my protocol, lines are
> terminated by "\r\n" -- not just "\n", like hGetLine expects it.
hGetLine should work fine, indeed that's what I used in the Haskell Web
Server. Each line will have an extra '\r' at the end, but you just need
to allow for that.
We really should have non-blocking versions of hGetBuf and hPutBuf, and
in fact I have the code sitting in my tree. I'll take a look and see if
it can be committed.
Cheers,
Simon
From simonmar at microsoft.com Tue Sep 16 15:32:45 2003
From: simonmar at microsoft.com (Simon Marlow)
Date: Tue Sep 16 09:32:57 2003
Subject: simpler I/O buffering [was: RE: An IO Question from a Newbie]
Message-ID: <3429668D0E777A499EE74A7952C382D1D84782@EUR-MSG-01.europe.corp.microsoft.com>
> Writing a sequence of characters across the interface I'm
> proposing is a
> request by the writing program for those characters to appear
> at their
> destination "soon". Ideally, "soon" would be "immediately";
> however, the
> characters' appearance may deliberately be delayed ("buffered"), for
> efficiency, as long as such delay is "unobtrusive" to a human
> user of the
> program. Buffering timeouts would depend on the device; for
> a terminal,
> perhaps 50-100 ms would be appropriate. Such an interval
> would tend not
> to be noticeable to a human user but would be long enough to
> effectively
> collect, say, an entire line of output for output "in one
> piece". The use
> of a reasonable timeout would avoid the confusing behavior where a
> newline-less prompt doesn't appear until the prompted data is entered.
So, let me see if I've understood: the situation would be exactly as
now, except that the buffer automatically gets flushed if it stays
non-empty for more than a certain time interval.
I don't think I like it: whatever time interval you choose will be too
long. If you're doing communication with another program, for example,
you really don't want to have the dialog stalled for 100ms doing
nothing. Sure, you could insert a flush, but only a programmer
knowledgeable about buffering will know to do that, or a programmer who
has debugged the program in detail to find out why it is sitting idle
most of the time.
So, in the end the programmer still needs to know about buffering. I'd
prefer it if the program didn't work at all when the flush is missing,
because it tells you immediately that something is wrong.
Cheers,
Simon
From simons at cryp.to Tue Sep 16 16:59:10 2003
From: simons at cryp.to (Peter Simons)
Date: Tue Sep 16 09:59:15 2003
Subject: Querying DNS from Haskell
Message-ID: <87brtk6dht.fsf@peti.cryp.to>
Hi,
is anyone aware of a library for Haskell, which allows to query domain
name servers for MX, A, and PTR records in a non-blocking way?
My first guess was to create an Interface to ADNS [1], but I figured,
maybe someone else has already solved this problem?
Peter
[1] http://www.gnu.org/software/adns/
From t.zielonka at students.mimuw.edu.pl Tue Sep 16 17:26:32 2003
From: t.zielonka at students.mimuw.edu.pl (Tomasz Zielonka)
Date: Tue Sep 16 10:26:40 2003
Subject: Querying DNS from Haskell
In-Reply-To: <87brtk6dht.fsf@peti.cryp.to>
References: <87brtk6dht.fsf@peti.cryp.to>
Message-ID: <20030916142631.GA31729@students.mimuw.edu.pl>
On Tue, Sep 16, 2003 at 03:59:10PM +0200, Peter Simons wrote:
> Hi,
>
> is anyone aware of a library for Haskell, which allows to query domain
> name servers for MX, A, and PTR records in a non-blocking way?
>
> My first guess was to create an Interface to ADNS [1], but I figured,
> maybe someone else has already solved this problem?
I have written such a library, but it is a bit incomplete now.
It is almost 100% pure Haskell (I had to use htonl/ntohl C functions in
one place because I prefer to keep IP addresses in host byte order and
Network.Socket.HostAddress uses network byte order).
The library contains a full DNS message parser and unparser.
I haven't yet implemented the full iterative query algorithm and CNAMEs
are not followed automatically.
I have used this library to concurrently resolve some millions of IP
addresses with performance of about 50 addresses per second.
If you are interested, I could clean it a bit and send you the library
with an example program.
> Peter
Best regards,
Tom
--
.signature: Too many levels of symbolic links
From Jon.Fairbairn at cl.cam.ac.uk Wed Sep 17 17:43:42 2003
From: Jon.Fairbairn at cl.cam.ac.uk (Jon Fairbairn)
Date: Wed Sep 17 11:43:48 2003
Subject: Improvement on this function
In-Reply-To: Your message of "Wed, 17 Sep 2003 10:31:11 EDT."
<1063809070.9361.3.camel@hanta.promisemark.com>
Message-ID: <11902.1063813422@cl.cam.ac.uk>
On 2003-09-17 at 10:31EDT Gordon James Miller wrote:
Something I think is more caf? than language:
> Hello all.
>
> I'd be interested in getting some feedback on how to do this linear
> interpolation function a little more cleanly. The normal way that this
> is taught is to find the set of indices in the x list that bracket the
> input value, then use the slope between these points to calculate the y
> value for the input value.
>
> I had a version working at one point using !! to access particular
> elements but I wasn't sure which one was the better solution.
!! can be expensive.
> linterp :: [Double] -> [Double] -> Double -> Double
> linterp (x1:x2:xs) (y1:y2:ys) x
> | x <= x2 || xs == [] = linterpPair x1 x2 y1 y2 x
> | otherwise = linterp (x2:xs) (y2:ys) x
> where linterpPair x1 x2 y1 y2 x = x1 + (x - x1) * (y2 - y1) / (x2 -
> x1)
It seems to me that you have too much going on in one
function. It would be better to break it into the part that
finds the point where the interpolation is supposed to
happen and the function that does the interpolation. You
sort-of do this, but don't go far enough for my taste.
You don't say whether the xs are supposed to be in
increasing order. Also it's not obvious that your version
does the right thing in the case where x < head xs, and
linterpPair doesn't look right to me.
Something like:
linterp :: [Double] -> [Double] -> Double -> Double
linterp xs ys x = linterpPair (neighbours (zip xs ys))
where linterpPair ((x1,y1),(x2,y2)) = y1 + (x - x1) * (y2 - y1) / (x2 - x1)
neighbours all@(p@(x1,y1):rest)
| x >= x1
= head (dropWhile (( Double -> Double
since that seems more natural as the data are connected that
way, and it would eliminate a zip.
--
J?n Fairbairn Jon.Fairbairn@cl.cam.ac.uk
From simons at cryp.to Wed Sep 17 19:48:14 2003
From: simons at cryp.to (Peter Simons)
Date: Wed Sep 17 12:48:18 2003
Subject: Fast I/O with sockets
References: <3429668D0E777A499EE74A7952C382D1D8471D@EUR-MSG-01.europe.corp.microsoft.com>
Message-ID: <877k47gy41.fsf@peti.cryp.to>
Simon Marlow writes:
> hGetLine should work fine, indeed that's what I used in the Haskell
> Web Server.
Well, another -- and more important -- problem with hGetLine is that
it will read an arbitrarily long line. An attacker might use this to
implement an denial-of-service attack simply by sending excessively
long lines, thus overflowing the stack / heap.
IMHO asynchronous hGetBuf / hPutBuf functions would really be the best
solution. (Or a way to set a read timeout for hGetContents ...)
Peter
From gk at ninebynine.org Thu Sep 18 14:44:07 2003
From: gk at ninebynine.org (Graham Klyne)
Date: Thu Sep 18 09:03:09 2003
Subject: (Off-topic) Question about categories
Message-ID: <5.1.0.14.2.20030918132357.02fdbf30@127.0.0.1>
(I'm asking here because I believe there is some overlap between category
theory and functional programming cognoscenti...)
It has been suggested to me that categories may be a useful framework (more
useful than set theory) for conceptualizing things for which there is no
well-defined equality relationship. (The discussion is about resources in
WWW.) I've done a little digging about category theory, and find some
relatively approachable material at:
http://www.wikipedia.org/wiki/Category_theory
http://www.wikipedia.org/wiki/Class_(set_theory)
and nearby.
But I'm hitting a mental block with this (and other places I've look don't
add anything I can grok). The definition of a category depends on the
definition of a morphism, and in particular the existence of an identity
morphism for every object in a category. The definition of an morphism is
in terms of equality of compositions of morphisms:
for f : A -> B we have Id[B]. f = f = f . Id[A]
My problem is this: how does it make sense to define an equality of
morphisms without some well-defined concept of equality on the underlying
objects to which they apply? That is, given object X and an object Y, it
is possible to examine them and determine whether or not they are the same
object. And if the underlying objects have such a concept of equality,
what prevents them from being sets or members of sets? But categories are
presented as being more general than sets.
Does anyone see the cause of my non-comprehension here?
#g
------------
Graham Klyne
GK@NineByNine.org
From franka at cs.uu.nl Thu Sep 18 16:53:30 2003
From: franka at cs.uu.nl (Frank Atanassow)
Date: Thu Sep 18 09:53:34 2003
Subject: (Off-topic) Question about categories
In-Reply-To: <5.1.0.14.2.20030918132357.02fdbf30@127.0.0.1>
Message-ID: <7C712576-E9DF-11D7-9F1B-0003936416C0@cs.uu.nl>
On donderdag, sep 18, 2003, at 14:44 Europe/Amsterdam, Graham Klyne
wrote:
> My problem is this: how does it make sense to define an equality of
> morphisms without some well-defined concept of equality on the
> underlying objects to which they apply? That is, given object X and
> an object Y, it is possible to examine them and determine whether or
> not they are the same object.
Yes; there is an equality relation on the objects.
The collection of objects of a (small) category forms a set. You can
only form sets of things which satisfy an equality relation, because
the extensionality axiom, which defines when two sets are equal, is
defined in terms of equality of members. By foundation, there has to be
an equality relation on the individuals in any such universe of sets.
> And if the underlying objects have such a concept of equality, what
> prevents them from being sets or members of sets?
I don't understand your confusion. The objects can certainly be sets;
the category of sets and functions (which is not small, BTW) is the
archetypal example. To determine if two sets are equal you use
extensionality: sets A and B are equal iff they have equal members.
Nothing prevents forming a set of objects either.
> But categories are presented as being more general than sets.
They're more general in the sense that:
a) the collection of objects can form a proper class, so a large
discrete (no non-identity arrows) category is "bigger" than any set;
b) the definition of a category involves more data than the
definition of a set. To define a set, you only need to specify its
elements. To define a category you need to give a collection of
objects, an indexed collection of homsets and a composition operator.
c) the collection of all sets forms one particular category.
> Does anyone see the cause of my non-comprehension here?
AFAICT, the source of your confusion is that you erroneously believed
that sets and/or members of sets couldn't (necessarily) be compared for
equality, but the fact is they always can, by definition. If the
category is large, there are additional issues, but there is still an
equality relation on the objects.
Does that clear things up?
Regards,
Frank
From alastair at reid-consulting-uk.ltd.uk Thu Sep 18 18:02:06 2003
From: alastair at reid-consulting-uk.ltd.uk (Alastair Reid)
Date: Thu Sep 18 12:02:10 2003
Subject: (Off-topic) Question about categories
In-Reply-To: <5.1.0.14.2.20030918132357.02fdbf30@127.0.0.1>
References: <5.1.0.14.2.20030918132357.02fdbf30@127.0.0.1>
Message-ID: <200309181702.06770.alastair@reid-consulting-uk.ltd.uk>
> But I'm hitting a mental block with this (and other places I've
> look don't add anything I can grok).
Two things I found useful when learning category theory are:
1) Try reading the definitions as though categories were just graphs:
Objects are nodes, morphisms are labelled edges and equality of morphism is
modulo some equivalence on lists of labels.
(Well, something like that - it's been a while since I played this game and
it's most useful for you to work out all the ins and outs of it yourself.)
2) Look for lots and lots of examples of categories.
Besides the obvious category of sets, there's domain theory (very useful to
help you get a handle on pushouts, initial, final, and the like), and lots
and lots of others. (Ask computer scientists for examples though - if you
have to learn topology before you can understand the categories that
mathematicians like to use, you won't gain much insight.)
Actually, these are just two different ways of saying to look beyond the
obvious Set category. The value of category theory is in its generalizations
and, especially, in its ability to draw parallels between many different
situations so looking at any one example for too long will tend to hold you
back.
--
Alastair Reid www.haskell-consulting.com
From diatchki at cse.ogi.edu Thu Sep 18 11:48:13 2003
From: diatchki at cse.ogi.edu (Iavor Diatchki)
Date: Thu Sep 18 13:48:19 2003
Subject: (Off-topic) Question about categories
In-Reply-To: <5.1.0.14.2.20030918132357.02fdbf30@127.0.0.1>
References: <5.1.0.14.2.20030918132357.02fdbf30@127.0.0.1>
Message-ID: <3F69EFDD.1080504@cse.ogi.edu>
hello,
i think what is importnat is that one can tell when two arrows are the
same (how to specify that of course is tricky in general). equality on
objects kind of follows from there. in fact one can describe a category
without referring to objects at all:
1. pick a collection of arrows (call it A)
2. pick a sub-collection if A that you will call "identity" arrows (call
that I)
3. give the following mappings (these are not arrows!)
3.1 source: A -> I
3.2 target: A -> I
3.3 compose: (A,A) -> A
(this one is partial, and has to be defined, when the source and
target match as usual).
the trick is that essentially objects are represented by the identity
arrows on them (as there is a 1-1 correspondance between the two).
my favourite way to think of a category is as follows:
1. i think of objects as types
2. i think of an arrow: A -> B as value of type B, that has a free
variable of type A
3. i think of composition as substitution
hope this helps
iavor
Graham Klyne wrote:
> (I'm asking here because I believe there is some overlap between
> category theory and functional programming cognoscenti...)
>
> It has been suggested to me that categories may be a useful framework
> (more useful than set theory) for conceptualizing things for which there
> is no well-defined equality relationship. (The discussion is about
> resources in WWW.) I've done a little digging about category theory,
> and find some relatively approachable material at:
> http://www.wikipedia.org/wiki/Category_theory
> http://www.wikipedia.org/wiki/Class_(set_theory)
> and nearby.
>
> But I'm hitting a mental block with this (and other places I've look
> don't add anything I can grok). The definition of a category depends on
> the definition of a morphism, and in particular the existence of an
> identity morphism for every object in a category. The definition of an
> morphism is in terms of equality of compositions of morphisms:
> for f : A -> B we have Id[B]. f = f = f . Id[A]
>
> My problem is this: how does it make sense to define an equality of
> morphisms without some well-defined concept of equality on the
> underlying objects to which they apply? That is, given object X and an
> object Y, it is possible to examine them and determine whether or not
> they are the same object. And if the underlying objects have such a
> concept of equality, what prevents them from being sets or members of
> sets? But categories are presented as being more general than sets.
>
> Does anyone see the cause of my non-comprehension here?
>
> #g
>
>
> ------------
> Graham Klyne
> GK@NineByNine.org
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
--
==================================================
| Iavor S. Diatchki, Ph.D. student |
| Department of Computer Science and Engineering |
| School of OGI at OHSU |
| http://www.cse.ogi.edu/~diatchki |
==================================================
From veger at cistron.nl Thu Sep 18 20:51:16 2003
From: veger at cistron.nl (Peter J. Veger)
Date: Thu Sep 18 13:51:22 2003
Subject: (Off-topic) Question about categories
In-Reply-To: <5.1.0.14.2.20030918132357.02fdbf30@127.0.0.1>
Message-ID: <000001c37e0d$757b10e0$0a02a8c0@veger3>
Graham Klyne wrote, on 18 september 2003 14:44
[...]
> But I'm hitting a mental block with this (and other places I've look don't
> add anything I can grok). The definition of a category depends on the
> definition of a morphism, and in particular the existence of an identity
> morphism for every object in a category. The definition of an morphism is
> in terms of equality of compositions of morphisms:
> for f : A -> B we have Id[B]. f = f = f . Id[A]
> My problem is this: how does it make sense to define an equality of
> morphisms without some well-defined concept of equality on the underlying
> objects to which they apply? That is, given object X and an object Y, it
> is possible to examine them and determine whether or not they are the same
> object. And if the underlying objects have such a concept of equality,
> what prevents them from being sets or members of sets? But categories are
> presented as being more general than sets.
I am not a specialist, but my understanding is as follows:
Category Theory is an axiomatic theory: a language with certain primitive
notions and relations between these notions.
Equality between objects is not a notion of category theory and you will not
find any category-theoretic theorem proving that two objects are equal.
(You may say that an object has an identity, as given by its identity
morphism. A category actually can be defined using morphisms only.)
Equality between morphisms however is a central notion of category theory.
If you have a concrete category, you have to denote some things as objects,
others as morphisms; before exploiting category theory, you have to prove
that the objects and morphisms of your concrete category fulfill the
category axioms, and for that you may, of course, use the equality relations
in your concrete category.
Peter J. Veger, Best Netherlands
From lektu at terra.es Thu Sep 18 21:16:33 2003
From: lektu at terra.es (Juanma Barranquero)
Date: Thu Sep 18 14:21:31 2003
Subject: How to detect finite/infinite lists?
Message-ID: <20030918200621.4D5B.LEKTU@terra.es>
Extremely-newbie questions:
Is there any way to know if a list is finite or infinite, other than
doing:
length l
and waiting forever? :)
I ask because I was learning Haskell by writing some pretty naive
implementation of surreal numbers, where I used lists for left and right
surreal sets, and I wanted to do some operations on the sets (like
finding the maximum/minimum), but obviously just on finite sets.
I vaguely suspect the answer is going to be: "No, because lists are lazy
(at least when they are :) and there's no general way to know beforehand
how many elements they're going to have". But still, if I write
x = [1..5]
the compiler knows pretty well x is not going to grow any new member...
(Unrelated) Is there any standard function to do:
interleave [] _ = []
interleave _ [] = []
interleave (x:xs) (y:ys) = x : y : interleave xs ys
It's pretty easy to implement as shown or via zipWith, but given that
Haskell 98 already includes some "basic" functions (like cycle, iterate,
etc.) I wonder if I've missed this one somehow.
Thanks,
/L/e/k/t/u
From brandon at its.caltech.edu Thu Sep 18 13:28:41 2003
From: brandon at its.caltech.edu (Brandon Michael Moore)
Date: Thu Sep 18 15:30:06 2003
Subject: How to detect finite/infinite lists?
In-Reply-To: <20030918200621.4D5B.LEKTU@terra.es>
References: <20030918200621.4D5B.LEKTU@terra.es>
Message-ID:
On Thu, 18 Sep 2003, Juanma Barranquero wrote:
> Extremely-newbie questions:
>
> Is there any way to know if a list is finite or infinite, other than
> doing:
>
> length l
>
> and waiting forever? :)
>
> I ask because I was learning Haskell by writing some pretty naive
> implementation of surreal numbers, where I used lists for left and right
> surreal sets, and I wanted to do some operations on the sets (like
> finding the maximum/minimum), but obviously just on finite sets.
>
> I vaguely suspect the answer is going to be: "No, because lists are lazy
> (at least when they are :) and there's no general way to know beforehand
> how many elements they're going to have". But still, if I write
>
> x = [1..5]
>
> the compiler knows pretty well x is not going to grow any new member...
Well, it's easy to tell that a list is finite by running length and having
it terminate. This is obviously equivalent to the halting problem so you
can't really expect anything better in general. Why do you need to test
whether lists are infinite? If your lists are being generated from finite
descriptions maybe you could use a data structure that records the
descriptions.
For example, rather than defining
l = [1..]++[2,3..7]
you could define
data EnumList = EnumFromBy Integer Integer
| EnumFromToBy Int Int Int
| Append EnumList EnumList
l = EnumFromBy 1 1 `Append` EnumFromToBy 2 1 7
then to test whether a list is infinite you can write
infinite (EnumFromBy _ _) = True
infinite (EnumFromToBy a delta b) = compare a delta == compare a b
infinite (Append l1 l2) = infinite l1 && infinite l2
Of course this only works if it is computable whether a description gives
a finite list.
> (Unrelated) Is there any standard function to do:
>
> interleave [] _ = []
> interleave _ [] = []
> interleave (x:xs) (y:ys) = x : y : interleave xs ys
>
> It's pretty easy to implement as shown or via zipWith, but given that
> Haskell 98 already includes some "basic" functions (like cycle, iterate,
> etc.) I wonder if I've missed this one somehow.
>
> Thanks,
Not as far as I know. The standard List module doesn't define anything
like that and Data.List doesn't define anything like that. What do you
want to use it for? If you are looking for strict alternation you should
use this defintion. If you want a nondeterministic merge as elements are
computed, look at mergeIO in Control.Concurrent in the GHC libraries.
Brandon
From ddarius at hotpop.com Thu Sep 18 16:53:12 2003
From: ddarius at hotpop.com (Derek Elkins)
Date: Thu Sep 18 15:55:20 2003
Subject: How to detect finite/infinite lists?
In-Reply-To: <20030918200621.4D5B.LEKTU@terra.es>
References: <20030918200621.4D5B.LEKTU@terra.es>
Message-ID: <20030918155312.000056c1.ddarius@hotpop.com>
On Thu, 18 Sep 2003 20:16:33 +0200
Juanma Barranquero wrote:
> Extremely-newbie questions:
>
> Is there any way to know if a list is finite or infinite, other than
> doing:
>
> length l
>
> and waiting forever? :)
In Haskell 98, no. With a slightly impure extension (observable
sharing) sometimes but in general, no. The only infinity you need to
recognize is omega and that's just an infinite (cyclic) list of
whatevers. So you -could- use observable sharing for this, but there
isn't much point to it, just use a data structure that says, "an
infinity of x". The simplest thing I would think of is to follow the
arithmetic operation exactly.
data SN
= Zero
| Up
| Down
| SN :+: SN
| SN :*: SN
| SN :^: SN
| Omega SN
omega = Omega Up
iota = Up :+: Omega Down
twoThirds = Omega (Up :+: Down)
twoOmega = Omega Up :+: Omega Up
omegaSquared = Omega Up :*: Omega Up
omegaToTheOmega = Omega Up :^: Omega Up
From lektu at terra.es Thu Sep 18 22:58:09 2003
From: lektu at terra.es (Juanma Barranquero)
Date: Thu Sep 18 15:58:15 2003
Subject: How to detect finite/infinite lists?
In-Reply-To: <055401c37e11$97aa4c90$6401a8c0@mauve>
References: <20030918200621.4D5B.LEKTU@terra.es>
<055401c37e11$97aa4c90$6401a8c0@mauve>
Message-ID: <20030918215305.4D61.LEKTU@terra.es>
On Thu, 18 Sep 2003 14:20:46 -0400, "David Barton" wrote:
> that's halting problem equivalent.
Yes, I know it's a halting problem, in the general case.
But the compiler could try to say if it knows it *is* a finite list. So:
x = [1..10]
y = [1..]
z = someFunctionOrOther
knownToBeFinite x -> should return Just True
knownToBeFinite y -> should return Just False
knownToBeFinite z -> should return Nothing ("I don't know").
or something along these lines.
> Nope.
Ok. Thanks,
/L/e/k/t/u
From lektu at terra.es Thu Sep 18 23:41:39 2003
From: lektu at terra.es (Juanma Barranquero)
Date: Thu Sep 18 16:41:41 2003
Subject: How to detect finite/infinite lists?
In-Reply-To:
References: <20030918200621.4D5B.LEKTU@terra.es>
Message-ID: <20030918223024.4D67.LEKTU@terra.es>
On Thu, 18 Sep 2003 12:28:41 -0700 (PDT), Brandon Michael Moore wrote:
> This is obviously equivalent to the halting problem so you
> can't really expect anything better in general.
No, obviously not in general. But a human wouldn't sweat to say that
[1..5] is finite and [1..] infinite. As I have no idea how the compiler
is implemented, I don't know if it knows whether what it has on its
hands is a fixed, short-length list (like [1..5], which I imagine the
compiler would perhaps pre-generate instead of lazy-evaluating it), or
one which in fact comes from some kind of generator function(s).
> Why do you need to test whether lists are infinite?
I had something like:
data Surreal = Surreal { leftSet::[Surreal], rightSet::[Surreal] }
where leftSet and rightSet could potentially contain infinite lists of
Surreals. Knowing that both sets are finite would allow to simplify some
numbers (in surreal numbers, it is the case that {-1|1} = {|}, for
example, and being able to simplify {-1|1} to {|} can help, specially
when trying to show/print the numbers).
> If your lists are being generated from finite
> descriptions maybe you could use a data structure that records the
> descriptions.
Yes, I think you're right.
> What do you want to use it for? If you are looking for strict alternation you
> should use this defintion.
Yes, strict alternation (output, in fact). I have lists of columns and
lists of separators and I interleave them while generating a line of
output.
Thanks,
/L/e/k/t/u
From lektu at terra.es Thu Sep 18 23:43:40 2003
From: lektu at terra.es (Juanma Barranquero)
Date: Thu Sep 18 16:43:51 2003
Subject: How to detect finite/infinite lists?
In-Reply-To: <20030918155312.000056c1.ddarius@hotpop.com>
References: <20030918200621.4D5B.LEKTU@terra.es>
<20030918155312.000056c1.ddarius@hotpop.com>
Message-ID: <20030918224257.4D6A.LEKTU@terra.es>
On Thu, 18 Sep 2003 15:53:12 -0400, Derek Elkins wrote:
> In Haskell 98, no. With a slightly impure extension (observable
> sharing) sometimes but in general, no.
Interesting.
> just use a data structure that says, "an
> infinity of x". The simplest thing I would think of is to follow the
> arithmetic operation exactly.
>
> data SN
> = Zero
> | Up
> | Down
> | SN :+: SN
> | SN :*: SN
> | SN :^: SN
> | Omega SN
:)
Thanks,
/L/e/k/t/u
From karczma at info.unicaen.fr Fri Sep 19 11:44:24 2003
From: karczma at info.unicaen.fr (Jerzy Karczmarczuk)
Date: Fri Sep 19 04:44:28 2003
Subject: Is this a terminologic issue?
References: <20030918200621.4D5B.LEKTU@terra.es>
<20030918223024.4D67.LEKTU@terra.es>
Message-ID: <3F6AC1E8.9060005@info.unicaen.fr>
[[Sent to Haskell-caf?, and to comp.lang.fun]]
If you look at some Web sites (Mathworld, the site of John Baez - a known
spec. in algebraic methods in physics), or into some books on differential
geometry, you might easily find something which is called pullback or
pull-back.
Actually, it is the construction of a dual, whose meaning can be distilled
and implemented in Haskell as follows. The stuff is very old, and very well
known.
Suppose you have two domains X and Y. A function F : X -> Y. The form (F x)
gives some y.
You have also a functor which constructs the dual spaces, X* and Y* - spaces
of functionals over X or Y. A function g belongs to Y* if g : Y -> Z (some
Z, let's keep one space like this).
Now, I can easily construct a dual to F, the function F* : Y* -> X* by
(F* g) x = g (F x)
and this mapping is called pullback...
While there is nothing wrong with that, and in Haskell one may easily
write the 'star' generator
(star f) g x = g (f x)
or
star = flip (.)
... I have absolutely no clue why this is called a pullback. Moreover, in
the incriminated diff. geom. books, its inverse is *not* called pushout,
but push-forward. Anyway, I cannot draw any pullback diagram from that.
The closest thing I found is the construction in Asperti & Longo,
where a F in C[A,B] induces F* : C!B -> C!A where the exclam.
sign is \downarrow, the "category over ...".
The diagram is there, a 9-edge prism, but - in my eyes - is quite
different from what one can get from this "contravariant composition"
above. But my eyes are not much better than my ears, so...
I sent this question to a few gurus, and the answers are not conclusive,
although it seems that this *is* a terminologic confusion.
Vincent Danos wrote:
> it really doesn't look like a categorical pullback
> and it might well be a "pull-back" only in the sense
> that if if F:A->B is a linear map say and f is a linear form on B, then F*(f)
> is a linear form on A
> defined as F*(f)(a)=f(b=F(a)) so one can "pull back" (linearly of course!)
> linear forms on B to linear forms on A
> "back" refers to the direction of F, i'd say.
==================================
Does anybody have a different (or any!) idea about that?
Thank you in advance for helping me to solve my homework.
Jerzy Karczmarczuk
Caen, France
From daniel_yokomiso at yahoo.com.br Fri Sep 19 09:01:12 2003
From: daniel_yokomiso at yahoo.com.br (Daniel Yokomiso)
Date: Fri Sep 19 06:55:59 2003
Subject: (Off-topic) Question about categories
References: <5.1.0.14.2.20030918132357.02fdbf30@127.0.0.1>
Message-ID: <030001c37e9d$86dcd310$0100000a@eonl9byru76yj2>
----- Original Message -----
From: "Graham Klyne"
To: "Haskell Cafe"
Sent: Thursday, September 18, 2003 9:44 AM
Subject: (Off-topic) Question about categories
> (I'm asking here because I believe there is some overlap between category
> theory and functional programming cognoscenti...)
>
> It has been suggested to me that categories may be a useful framework
(more
> useful than set theory) for conceptualizing things for which there is no
> well-defined equality relationship. (The discussion is about resources in
> WWW.) I've done a little digging about category theory, and find some
> relatively approachable material at:
> http://www.wikipedia.org/wiki/Category_theory
> http://www.wikipedia.org/wiki/Class_(set_theory)
> and nearby.
>
> But I'm hitting a mental block with this (and other places I've look don't
> add anything I can grok). The definition of a category depends on the
> definition of a morphism, and in particular the existence of an identity
> morphism for every object in a category. The definition of an morphism is
> in terms of equality of compositions of morphisms:
> for f : A -> B we have Id[B]. f = f = f . Id[A]
>
> My problem is this: how does it make sense to define an equality of
> morphisms without some well-defined concept of equality on the underlying
> objects to which they apply? That is, given object X and an object Y, it
> is possible to examine them and determine whether or not they are the same
> object. And if the underlying objects have such a concept of equality,
> what prevents them from being sets or members of sets? But categories are
> presented as being more general than sets.
>
> Does anyone see the cause of my non-comprehension here?
>
> #g
>
>
> ------------
> Graham Klyne
> GK@NineByNine.org
Hi,
There's some additional links about category theory in this LtU
discussion: http://lambda.weblogs.com/discuss/msgReader$979. Also there's
this presentation "Category Theory for Beginners"
http://www.cs.toronto.edu/~sme/presentations/cat101.pdf. HTH.
Best regards,
Daniel Yokomiso.
"Honesty is the best policy, but insanity is a better defense."
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.518 / Virus Database: 316 - Release Date: 12/9/2003
From GK at ninebynine.org Mon Sep 22 14:28:48 2003
From: GK at ninebynine.org (Graham Klyne)
Date: Mon Sep 22 08:35:00 2003
Subject: Thanks: (was Question about categories)
Message-ID: <5.1.0.14.2.20030922130621.00bbab10@127.0.0.1>
Thanks to everyone who responded to my question about category theory.
The responses turned up some interesting and useful material on the web,
which I'm still digesting. Notably [1] [2].
There's something in the introduction of [2] that I think will help me get
a handle on this:
[[
... objects are not collections of "elements," and morphisms do not need to
be functions between sets (thus morphisms cannot be applied to "elements"
but only composed with other morphisms). Any immediate access to the
internal structure of objects is prevented: all properties of objects must
be specified by properties of morphisms ...
]]
My earlier supposition was that an "object" was roughly in correspondence
with a member of a set, but I'm coming to perceive that "object"
corresponds more with the notion of a set or collection of some
(unspecified) things.
#g
--
[1] http://www.cs.toronto.edu/~sme/presentations/cat101.pdf
[2] http://www.di.ens.fr/users/longo/download.html
which has a link to content of the (apparently) out-of-print book:
[[
CATEGORIES TYPES AND STRUCTURES
An Introduction to Category Theory for the working computer scientist
Andrea Asperti
Giuseppe Longo
FOUNDATIONS OF COMPUTING SERIES, M.I.T. PRESS, 1991
]]
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
------------
Graham Klyne
GK@NineByNine.org
From jcast at cate0-46.reshall.ou.edu Sun Sep 21 22:02:57 2003
From: jcast at cate0-46.reshall.ou.edu (Jon Cast)
Date: Mon Sep 22 08:57:27 2003
Subject: An IO Question from a Newbie
In-Reply-To: Message from Derek Elkins
"of Fri, 12 Sep 2003 19:17:05 EDT."
<20030912191705.0000677a.ddarius@hotpop.com>
References: <200309121627.59788.angagon@earthlink.net>
<20030912191705.0000677a.ddarius@hotpop.com>
Message-ID:
> On Fri, 12 Sep 2003 16:27:59 -0600
> Matt O'Connor wrote:
>
> > Hello all. I'm new to functional programming and Haskell, but have
> > been programming in C and Java for a while. I've been going through
> > the tutorials and whatnot on haskell.org. I've read from the Gentle
> > Introduction to Haskell about IO and some of the other stuff and I
> > have a question about it.
> >
> > main = do putStr "Type Something: "
> > str <- getLine
> > putStrLn ("You typed: " ++ str)
> >
> > When compile and run this code the "Type Something: " isn't displayed
> > until the putStrLn. So there is no prompt. The output looks like
> > this.
> >
> > s
> > Type Something: You typed: s
> >
> > But if I change the putStr "Type Something: " to a putStrLn or put a
> > \n at the end of the string it displays the text immediately (ie, when
> > I want it to). Is there a good reason for this? Am I doing something
> > wrong? Or do I need to call some kind of standard output flush?
>
> Yes, the problem is that the first line is not being flushed. Importing
> hFlush and stdout from IO (or System.IO) and adding hFlush stdout after
> you putStr will fix it. Alternatively, you could change the buffering
> on stdout to NoBuffering. I don't know if there is a standard
> putStrWithFlush function or just a better answer than this. A
> putStrWithFlush would be trivial to write or more generally to a
> HOF that flushed after performing the action passed to it.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Just thought I'd point out (in case it isn't clear) that this function
is flushAfter h a = liftM2 const a (hFlush h). Not much of an
improvement...
Jon Cast
From Alistair_Bayley at ldn.invesco.com Mon Sep 22 13:10:36 2003
From: Alistair_Bayley at ldn.invesco.com (Bayley, Alistair)
Date: Mon Sep 22 08:57:28 2003
Subject: garbage collection and Ptr/ForeignPtr/StablePtr
Message-ID: <7DFF3BC6CA957441AEADA7F340BFAA3401B33735@GBLONEX11.lon.invesco.com>
Should I expect that Ptr memory allocated with malloc is garbage collected
when no longer used by the Haskell runtime? The FFI spec doesn't say so
explicitly (that I could see); AFAICT this is how the pointer types behave:
Ptr : freed when no longer used/referenced
ForeignPtr : like Ptr, but will also run a finaliser when freed
StablePtr : not freed or collected
(I haven't tested this; I've only read the FFI spec.)
*****************************************************************
The information in this email and in any attachments is
confidential and intended solely for the attention and use
of the named addressee(s). This information may be
subject to legal professional or other privilege or may
otherwise be protected by work product immunity or other
legal rules. It must not be disclosed to any person without
our authority.
If you are not the intended recipient, or a person
responsible for delivering it to the intended recipient, you
are not authorised to and must not disclose, copy,
distribute, or retain this message or any part of it.
*****************************************************************
From simonmar at microsoft.com Mon Sep 22 15:11:04 2003
From: simonmar at microsoft.com (Simon Marlow)
Date: Mon Sep 22 09:09:44 2003
Subject: garbage collection and Ptr/ForeignPtr/StablePtr
Message-ID: <3429668D0E777A499EE74A7952C382D1DFE276@EUR-MSG-01.europe.corp.microsoft.com>
> Should I expect that Ptr memory allocated with malloc is
> garbage collected
> when no longer used by the Haskell runtime? The FFI spec
> doesn't say so
> explicitly (that I could see); AFAICT this is how the pointer
> types behave:
> Ptr : freed when no longer used/referenced
> ForeignPtr : like Ptr, but will also run a finaliser when freed
> StablePtr : not freed or collected
No, all memory that you allocate with the FFI must be freed explicitly.
You can arrange for memory to be deallocated when no longer referenced
by using a ForeignPtr, and using the finalizer to free the memory. Bear
in mind that if your application has large, or strict, memory
requirements, then relying on the ForeignPtr method may not be the best
solution, because finalizers can be unpredictable.
Cheers,
Simon
From daniel_yokomiso at yahoo.com.br Mon Sep 22 14:38:00 2003
From: daniel_yokomiso at yahoo.com.br (=?iso-8859-1?q?Daniel=20Yokomiso?=)
Date: Mon Sep 22 12:38:03 2003
Subject: Thanks: (was Question about categories)
In-Reply-To: <5.1.0.14.2.20030922130621.00bbab10@127.0.0.1>
Message-ID: <20030922163800.30111.qmail@web40603.mail.yahoo.com>
--- Graham Klyne escreveu:
[snip]
> [2] http://www.di.ens.fr/users/longo/download.html
> which has a link to content of the (apparently)
> out-of-print book:
> [[
> CATEGORIES TYPES AND STRUCTURES
> An Introduction to Category Theory for the working
> computer scientist
> Andrea Asperti
> Giuseppe Longo
> FOUNDATIONS OF COMPUTING SERIES, M.I.T. PRESS, 1991
> ]]
Seems to be this book:
http://www.amazon.com/exec/obidos/tg/detail/-/0262011255/qid=1064248079/sr=8-1/ref=sr_8_1/002-2181686-7144062?v=glance&s=books&n=507846
There's also a list of some books about it:
http://www.booksunderreview.com/Science/Math/Algebra/Category_Theory/
BTW I tried to connect to
ftp.ens.fr/pub/dmi/users/longo/CategTypesStructures
(as informed in an Amazon review) but failed. Someone
knows of another place where we can legally obtain the
postscript files (if they exist at all)?
Best regards,
Daniel Yokomiso.
_______________________________________________________________________
Desafio AntiZona: participe do jogo de perguntas e respostas que vai
dar um Renault Clio, computadores, c?meras digitais, videogames e muito
mais! www.cade.com.br/antizona
From diatchki at cse.ogi.edu Mon Sep 22 12:27:53 2003
From: diatchki at cse.ogi.edu (Iavor Diatchki)
Date: Mon Sep 22 14:27:57 2003
Subject: Thanks: (was Question about categories)
In-Reply-To: <20030922163800.30111.qmail@web40603.mail.yahoo.com>
References: <20030922163800.30111.qmail@web40603.mail.yahoo.com>
Message-ID: <3F6F3F29.20708@cse.ogi.edu>
hi,
for the book mentioned bellow (and many other useful texts) check out
frank atanassow page:
http://www.cs.uu.nl/people/franka/ref
hope this helps
iavor
Daniel Yokomiso wrote:
> --- Graham Klyne escreveu:
>
> [snip]
>
>
>>[2] http://www.di.ens.fr/users/longo/download.html
>>which has a link to content of the (apparently)
>>out-of-print book:
>>[[
>>CATEGORIES TYPES AND STRUCTURES
>>An Introduction to Category Theory for the working
>>computer scientist
>>Andrea Asperti
>>Giuseppe Longo
>>FOUNDATIONS OF COMPUTING SERIES, M.I.T. PRESS, 1991
>>]]
>
>
> Seems to be this book:
>
> http://www.amazon.com/exec/obidos/tg/detail/-/0262011255/qid=1064248079/sr=8-1/ref=sr_8_1/002-2181686-7144062?v=glance&s=books&n=507846
>
> There's also a list of some books about it:
>
> http://www.booksunderreview.com/Science/Math/Algebra/Category_Theory/
>
> BTW I tried to connect to
> ftp.ens.fr/pub/dmi/users/longo/CategTypesStructures
> (as informed in an Amazon review) but failed. Someone
> knows of another place where we can legally obtain the
> postscript files (if they exist at all)?
>
> Best regards,
> Daniel Yokomiso.
>
>
> _______________________________________________________________________
> Desafio AntiZona: participe do jogo de perguntas e respostas que vai
> dar um Renault Clio, computadores, c?meras digitais, videogames e muito
> mais! www.cade.com.br/antizona
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
--
==================================================
| Iavor S. Diatchki, Ph.D. student |
| Department of Computer Science and Engineering |
| School of OGI at OHSU |
| http://www.cse.ogi.edu/~diatchki |
==================================================
From bhalchin at hotmail.com Mon Sep 22 21:38:12 2003
From: bhalchin at hotmail.com (Bill Halchin)
Date: Mon Sep 22 16:38:15 2003
Subject: Thanks: (was Question about categories)
Message-ID:
An HTML attachment was scrubbed...
URL: http://porky.devel.redhat.com/pipermail/haskell-cafe/attachments/20030922/6b3dcbf0/attachment.htm
From florian at hars.de Tue Sep 23 09:37:24 2003
From: florian at hars.de (Florian Hars)
Date: Tue Sep 23 02:37:37 2003
Subject: Thanks: (was Question about categories)
In-Reply-To:
References:
Message-ID: <3F6FEA24.2050908@hars.de>
Bill Halchin wrote:
> Here is the book plus many other llongo papers:
> http://www.di.ens.fr/users/llongo/download.html
s/llongo/longo/
From alastair at reid-consulting-uk.ltd.uk Tue Sep 23 13:11:01 2003
From: alastair at reid-consulting-uk.ltd.uk (Alastair Reid)
Date: Tue Sep 23 07:11:07 2003
Subject: garbage collection and Ptr/ForeignPtr/StablePtr
In-Reply-To: <7DFF3BC6CA957441AEADA7F340BFAA3401B33735@GBLONEX11.lon.invesco.com>
References: <7DFF3BC6CA957441AEADA7F340BFAA3401B33735@GBLONEX11.lon.invesco.com>
Message-ID: <200309231211.01984.alastair@reid-consulting-uk.ltd.uk>
On Monday 22 September 2003 12:10 pm, Bayley, Alistair wrote:
> Should I expect that Ptr memory allocated with malloc is garbage collected
> when no longer used by the Haskell runtime? The FFI spec doesn't say so
> explicitly (that I could see);
C programs use pointers in many ways: pointers to static objects, pointers to
stack-allocated objects, etc. as well as pointers to malloc-allocated
objects. These are all represented with a 'Ptr' in Haskell but only one of
them should be freed.
Also, there are many ways to free a malloced object in C programs. You might
have to decrement a reference count, you might have to first free any objects
it contains pointers to, you might call a library-specific free routine
called 'xfree', you might call a type-specific freeing routine or you might
just call free.
For all these reasons, Haskell's garbage collector cannot just call 'free' for
you.
> AFAICT this is how the pointer types behave:
> Ptr : freed when no longer used/referenced
No.
If it needs freed, you have to explicitly deallocate this by calling an
appropriate routine.
This effectively means that you use Ptr for things accessed inside the IO
monad.
> ForeignPtr : like Ptr, but will also run a finaliser when freed
Yes. The finalizer is (a pointer to) any C function you like.
ForeignPtr is especially useful for datatypes accessed outside the IO monad.
e.g., if you wanted to use a complex number library, you might use ForeignPtr
for the freeing function.
ForeignPtr is also useful even if you are in the IO monad when you don't have
a simple access pattern like 'allocate; use; free;'.
Note that the ffi libraries provide functions called 'malloc' and 'free' and a
finalizer called 'finalizerFree'. It is tempting to think that these are the
C library 'malloc'/'free' and (a pointer to) 'free'. This is not necessarily
so and you must take care that:
- you only use MarshallAlloc.free and MarshallAlloc.finalizerFree with
memory allocated using MarshallAlloc.malloc
- you only use libc's 'free' with memory allocated using libc's 'malloc'.
> StablePtr : not freed or collected
Yes. StablePtrs are in a different category because they are pointers from C
into Haskell (in contrast, Ptrs and ForeignPtrs are pointers from Haskell
into C). Since C doesn't have garbage collection, it is up to your C code to
explicitly call 'freeStablePtr'.
> (I haven't tested this; I've only read the FFI spec.)
I had a quick reread of sections 5.4 and 5.5 and I think your confusion is
understandable. It doesn't say anything about deallocation so you might
plausibly guess that the story is the same as for Int8 (say) which also says
nothing about deallocation. ForeignPtrs are contrasted with Ptrs but only in
whether or not they have finalizers.
I think the ffi spec has now been finalized so it's too late to fix this but
perhaps the next revision could include the following wording (inserted after
the first sentence of section 5.4).
Objects of type 'Ptr a' and 'FunPtr a' are garbage collected
in the normal way but the objects they _point to_ are not garbage
collected. If the objects pointed to require deallocation, this
must be done by explicitly calling an appropriate function such as
the C library function 'free'.
I have put some of the above in my FFI guide at:
http://www.reid-consulting-uk.ltd.uk/docs/ffi.html
--
Alastair Reid www.haskell-consulting.com
From simons at cryp.to Tue Sep 23 16:06:19 2003
From: simons at cryp.to (Peter Simons)
Date: Tue Sep 23 09:06:24 2003
Subject: Generating "setMember" functions for record structures
Message-ID: <87wubzr6wk.fsf@peti.cryp.to>
Hi,
in one of my programs, I have to modify individual fields of a pretty
large record structure quite frequently. Assume the structure is:
> data State = State { foo :: [Int]
> , bar :: [String]
> }
Then I'd like to have functions setFoo and setBar, which copy a State
but replace the field in question with a given value. This is
implemented as:
> setFoo :: State -> [Int] -> State
> setFoo st x = State { foo = x
> , bar = bar st
> }
> setBar :: State -> [String] -> State
> setBar st x = State { foo = foo st
> , bar = x
> }
Now, defining these helper functions for large records is not what I
call an interesting job.
Thus I wonder, is there any way to automate this task? I thought about
using Template Haskell, but I haven't used it at all yet and am
uncertain about how difficult accomplishing this would be.
I also thought about using "Data.Generics", which I know better, but
the generic approach feels like over-kill for this task. In order to
use it, I'd have to re-design my data structure as well. So this isn't
too attractive ...
Any ideas? Comments? Source Code? :-)
Peter
From maeder at tzi.de Tue Sep 23 16:38:16 2003
From: maeder at tzi.de (Christian Maeder)
Date: Tue Sep 23 09:38:26 2003
Subject: Generating "setMember" functions for record structures
In-Reply-To: <87wubzr6wk.fsf@peti.cryp.to>
References: <87wubzr6wk.fsf@peti.cryp.to>
Message-ID: <3F704CC8.4020105@tzi.de>
>>setFoo :: State -> [Int] -> State
>>setFoo st x = State { foo = x
>> , bar = bar st
>> }
>
>
>>setBar :: State -> [String] -> State
>>setBar st x = State { foo = foo st
>> , bar = x
>> }
It should be sufficient to just write:
setFoo st x = st { foo = x }
setBar st x = st { bar = x }
This creates a new State (out of "st") with an updated field entry
without mentioning the other fields.
Christian
From Malcolm.Wallace at cs.york.ac.uk Tue Sep 23 15:35:51 2003
From: Malcolm.Wallace at cs.york.ac.uk (Malcolm Wallace)
Date: Tue Sep 23 09:40:24 2003
Subject: Generating "setMember" functions for record structures
In-Reply-To: <87wubzr6wk.fsf@peti.cryp.to>
References: <87wubzr6wk.fsf@peti.cryp.to>
Message-ID: <20030923143551.78611cb3.Malcolm.Wallace@cs.york.ac.uk>
Peter Simons writes:
> > setFoo :: State -> [Int] -> State
> > setFoo st x = State { foo = x
> > , bar = bar st
> > }
There is an easier way to do this, using the record update syntax
rather than record construction syntax. e.g.
setFoo st x = st { foo = x }
All the unmentioned fields retain their previous values from the
'st' structure.
Regards,
Malcolm
From Alistair_Bayley at ldn.invesco.com Tue Sep 23 15:29:20 2003
From: Alistair_Bayley at ldn.invesco.com (Bayley, Alistair)
Date: Tue Sep 23 10:03:20 2003
Subject: Database interface - would like advice on oracle library binding
Message-ID: <7DFF3BC6CA957441AEADA7F340BFAA3401B33742@GBLONEX11.lon.invesco.com>
(2nd attempt; mailman thinks I'm not a list member, but it still keeps
sending me mail.)
Still making slow progress on an Oracle database binding... now I'm trying
to fit the API I have into some sort of abstract interface (like the one(s)
discussed previously:
http://haskell.org/pipermail/haskell-cafe/2003-August/004957.html ).
1. Is the left-fold the best/only interface to expose? I think yes, but that
doesn't allow fine-grained control over cursors i.e. being able to open many
cursors at once and interleave fetches from them. Or does it?
2. I'm finding it hard to write a doQuery function that takes an extraction
function that isn't a pig to write. Some advice would be useful here... (and
a long-ish explanation follows):
The Oracle Call Interface (OCI) requires that I allocate buffers for the
result of a single row fetch, before the first row is fetched. So a query
involves:
- prepare statement etc
- allocate buffers (one for each column - call OCI C function
"DefineByPos")
- fetch row
- extract/marshal data from buffer into Haskell types (which are then
processed by fold function)
- fetch, marshal (repeat until no more rows)
- free buffers
i.e. the same buffers are re-used for each row.
The problem for me is how to specify the left-fold function in terms of the
low-level API. If I want to supply extraction functions (to extract Haskell
values from result buffer), how do I manage the buffer allocation in the
doQuery function? The buffer allocate/free code also needs to know the
column positions and types, in the same manner as the extract functions.
I want to be able to write code like this:
results <- doQuery dbconn sqltext [] \row results -> do
name <- stringv row 1
address <- stringv row 2
return (name,address):results
.. where the stringv function extracts/marshals a Haskell String from the
result buffer.
The intermediate approach I currently have means I have to pass an IO action
into the doQuery function that, when evaluated, allocates the buffer and
returns two more actions:
- an action that extracts the row as a tuple
- another action that frees the buffer
The doQuery function evaluates the initial action (to allocate the buffer),
uses the extract action to build the result (at present a list), and when
there are no more rows, uses the free action to free the buffer.
This approach is quite awkward (especially w.r.t. writing extract
functions), and it's hard for me to see how to build a better interface.
Hard, because of the memory management requirements.
--------------------
Here's a chunk of the code. A lot of it is OCI plumbing, but I hope you can
see how awkward it is to create an extract function (see ex3 at the bottom).
Given pointers to the buffer, extract a string of variable length (you have
to terminate it yourself).
> fetchStringVal :: OCIColInfo -> IO String
> fetchStringVal (_, bufptr, nullindptr, retsizeptr) = do
> retsize <- liftM cShort2Int (peek retsizeptr)
> nullind <- liftM cShort2Int (peek nullindptr) -- unused
> pokeByteOff (castPtr bufptr) retsize nullByte
> val <- peekCString (castPtr bufptr)
> return val
Free a single column's buffer.
> freeColBuffer :: OCIColInfo -> IO ()
> freeColBuffer (_, bufptr, nullindptr, retsizeptr) = do
> free bufptr
> free retsizeptr
> free nullindptr
Create a buffer for a string column, and return the extract and free IO
actions.
> getExtractFnString :: Int -> ErrorHandle -> StmtHandle -> IO (IO String,
IO ())
> getExtractFnString posn err stmt = do
> c <- defineCol err stmt posn 2000 oci_SQLT_CHR
> return ((fetchStringVal c), (freeColBuffer c))
doQuery uses the extractFns action to create the result buffer,
and the two actions (extract and free) which are passed to doQuery2.
> doQuery2 :: ErrorHandle -> StmtHandle -> IO a -> IO () -> [a] -> IO [a]
> doQuery2 err stmt extractData freeMem results = do
> rc <- fetch err stmt
> if rc == oci_NO_DATA
> then do
> freeMem
> return results
> else do
> v <- extractData
> doQuery2 err stmt extractData freeMem (v:results)
> doQuery :: Session -> String -> (ErrorHandle -> StmtHandle -> IO (IO a, IO
())) -> IO [a]
> doQuery (Sess env err con) qry extractFns = do
> stmt <- getStmt env err
> prepare err stmt qry
> execute err con stmt
> (extractData, freeMem) <- extractFns err stmt
> doQuery2 err stmt extractData freeMem []
The interface provided by doQuery means I have to write extract functions
like this.
Here's one for a select that returns three String columns.
It's quite awkward...
> ex3 :: ErrorHandle -> StmtHandle -> IO (IO (String, String, String), IO
())
> ex3 err stmt = do
> (fetchcol1, freecol1) <- getExtractFnString 1 err stmt
> (fetchcol2, freecol2) <- getExtractFnString 2 err stmt
> (fetchcol3, freecol3) <- getExtractFnString 3 err stmt
> return
> ( do { s1 <- fetchcol1; s2 <- fetchcol2; s3 <- fetchcol3; return (s1,
s2, s3) }
> , do { freecol1; freecol2; freecol3 }
> )
*****************************************************************
The information in this email and in any attachments is
confidential and intended solely for the attention and use
of the named addressee(s). This information may be
subject to legal professional or other privilege or may
otherwise be protected by work product immunity or other
legal rules. It must not be disclosed to any person without
our authority.
If you are not the intended recipient, or a person
responsible for delivering it to the intended recipient, you
are not authorised to and must not disclose, copy,
distribute, or retain this message or any part of it.
*****************************************************************
From Tom.Pledger at peace.com Wed Sep 24 13:08:15 2003
From: Tom.Pledger at peace.com (Tom Pledger)
Date: Tue Sep 23 20:08:28 2003
Subject: Database interface - would like advice on oracle library binding
In-Reply-To: <7DFF3BC6CA957441AEADA7F340BFAA3401B33742@GBLONEX11.lon.invesco.com>
References: <7DFF3BC6CA957441AEADA7F340BFAA3401B33742@GBLONEX11.lon.invesco.com>
Message-ID: <16240.57455.812576.183573@tux-17.corp.peace.com>
Bayley, Alistair writes:
:
| Still making slow progress on an Oracle database binding... now I'm trying
| to fit the API I have into some sort of abstract interface (like the one(s)
| discussed previously:
| http://haskell.org/pipermail/haskell-cafe/2003-August/004957.html ).
|
|
| 1. Is the left-fold the best/only interface to expose? I think yes,
| but that doesn't allow fine-grained control over cursors i.e. being
| able to open many cursors at once and interleave fetches from
| them. Or does it?
It looks like the interleaving would be limited to a nested loop
structure: a cursor could be processed in full during one extraction
for another cursor.
Application-side nested loop structures are often a poor substitute
for server-side joins.
| 2. I'm finding it hard to write a doQuery function that takes an
| extraction function that isn't a pig to write. Some advice would be
| useful here... (and a long-ish explanation follows):
:
Here's my attempt to summarise the piggishness you describe:
The interface to Oracle requires that you initialise a cursor by
allocating a suitably typed buffer for each column prior to
fetching the first row, and finalise a cursor by freeing those
buffers after fetching the last row.
This means that we must iterate over the columns 3 times. We
would prefer to express this iteration only once, and have the
other 2 happen automatically within the library. (As opposed to
what ex3 does, which is to iterate for getExtractFnString, iterate
for fetchcolN, and iterate for freecolN.)
Here's one approach: find the OCI equivalent of JDBC's
ResultSetMetaData, and use it to drive the allocation and freeing of
buffers.
Here's another:
Add a mode attribute to the abstract data type which encompasses
ErrorHandle and StmtHandle. (I'll persist in referring to that
ADT as Cursor.)
Expect extraction functions to be written along these lines:
\cursor result
-> do field1 <- getInt cursor
field2 <- getString cursor
field3 <- getString cursor
return ((field1, field2, field3):result, True)
Make getInt (and friends) behave differently depending on the mode
of the cursor they're passed: either allocate a buffer and return
_|_, decode and return the current column of the current row, or
free a buffer and return _|_.
doQuery could then apply the extraction function once in Allocate
mode after opening the cursor, once per fetched row in Decode
mode, and once in Free mode at the end.
There's nothing to stop an extraction function from varying the number
of get___ functions it applies, or trying to match their results when
not in Decode mode. These weakness could be mitigated by:
Pointing out that some database connection standards (JDBC, and
for all I know also ODBC) don't guarantee that you can still get
at a row's 1st column after you've looked at its 2nd column,
i.e. there's a precedent for such fragility.
Complicating the extraction functions by giving them the type
(Cursor -> b -> IO (IO (b, Bool)))
, expecting that all the get___ functions are applied in the outer
IO layer, and undertaking that the inner IO layer will only be
used in Decode mode.
Regards,
Tom
From oleg at pobox.com Tue Sep 23 22:51:08 2003
From: oleg at pobox.com (oleg@pobox.com)
Date: Wed Sep 24 00:51:28 2003
Subject: Database interface - would like advice on oracle library binding
In-Reply-To:
<7DFF3BC6CA957441AEADA7F340BFAA3401B33742@GBLONEX11.lon.invesco.com>
Message-ID: <200309240451.h8O4p8ic023176@adric.fnmoc.navy.mil>
> 1. Is the left-fold the best/only interface to expose? I think yes, but that
> doesn't allow fine-grained control over cursors i.e. being able to open many
> cursors at once and interleave fetches from them. Or does it?
I'd like to remark first that many real databases let us avoid opening
many cursors at once. It seems to be more efficient to do as much as
possible within the engine -- using the full power of SQL or Stored
Procedures -- and relay only the final results through the
boundary. We can use SELECT ... UNION, correlated subqueries, SELECT
rowid, self (outer) joins, etc. There are cases where SQL is powerless
-- a transitive closure comes to mind. Stored procedures may sometimes
help. A stored procedure may return a 'row' and thus can be used as a
"generator" in Icon or Ruby's sense of the word.
Still, opening several cursors may be unavoidable. The left fold
approach may still help -- we _can_ mechanically invert a left fold
combinator (to be precise, a half-baked version of it) into a lazy
list. Please see a separate message "how to invert the left fold"
> This approach is quite awkward (especially w.r.t. writing extract
> functions), and it's hard for me to see how to build a better interface.
> Hard, because of the memory management requirements.
I believe the extract functions can be constructed automatically --
similar to the way Quickcheck constructs test cases. I believe that
instead of
> results <- doQuery dbconn sqltext [] \row results -> do
> name <- stringv row 1
> address <- stringv row 2
> return (name,address):results
we can do
results <- doQuery dbconn sqltext [] process
where
process:: String -> String -> [(String,String)] -> [(String,String)]
process name address results = (name,address):results
doQuery should be able to figure our that the function 'process' takes
two arguments of type string. Therefore, doQuery needs to extract two
columns from the current row, both of type string. Note, 'process' is
a pure function. There is no reason for it to be monadic (if it
doesn't have to be). Because doQuery is a left-fold iterator, it can
keep reusing buffers until the iteration finishes. We can keep the
pointers to column buffers in a polytipic list, and we can keep the
corresponding deallocation actions in a list of IO (). When we prepare
a statement, we create both lists. When we finish doQuery, we scan the
list of destructor actions and execute them to free all the
buffers. It's hard for me to write the corresponding code because I
don't have Oracle handy (besides, I like Informix better). Is it
possible to come up with a "stub" that uses flat files? We are only
interested in fetching rows. It doesn't matter if these rows come from
a file or from a database. That would make prototyping the interface
quite easier.
From Alistair_Bayley at ldn.invesco.com Wed Sep 24 11:44:16 2003
From: Alistair_Bayley at ldn.invesco.com (Bayley, Alistair)
Date: Wed Sep 24 05:47:58 2003
Subject: Database interface - would like advice on oracle library bind
ing
Message-ID: <7DFF3BC6CA957441AEADA7F340BFAA3401B33749@GBLONEX11.lon.invesco.com>
> From: oleg@pobox.com [mailto:oleg@pobox.com]
>
> I'd like to remark first that many real databases let us avoid opening
> many cursors at once. It seems to be more efficient to do as much as
> possible within the engine ...
I agree (and Tom Pledger makes the same comment). It's rare that I want to
have more than one cursor open at once. When I've seen other developers do
it, they're often doing something that would be better accomplished as a
join. And that last time I remember doing it, it was a nested loops
situation (which, on reflection, probably could have been done as a join...
oh well).
OTOH, I have seen interleaved fetches used to simulate a join where the
specific DBMS product struggled to perform the join efficiently itself. In
this case the developer is making up for a deficiency in the DBMS, and I
don't want to exclude the option from the interface (if you agree with what
you read on http://www.dbdebunk.com , then most DBMS products are deficient
in a number of ways).
> Still, opening several cursors may be unavoidable. The left fold
> approach may still help -- we _can_ mechanically invert a left fold
> combinator (to be precise, a half-baked version of it) into a lazy
> list. Please see a separate message "how to invert the left fold"
Found it. I'll have a look...
> I believe the extract functions can be constructed automatically --
> similar to the way Quickcheck constructs test cases. I believe that
> instead of
I though this might be possible, but I had no idea how to do it. I'll have a
look at the Quickcheck source to see how it's done, unless you can suggest a
better example.
> buffers. It's hard for me to write the corresponding code because I
> don't have Oracle handy (besides, I like Informix better). Is it
> possible to come up with a "stub" that uses flat files? We are only
> interested in fetching rows. It doesn't matter if these rows come from
> a file or from a database. That would make prototyping the interface
> quite easier.
I wasn't interested so much in prototyping the interface, as trying to write
an implementation that supported the interface(s) discussed previously. I
intended to provide the left-fold interface, and was wondering if that was
all that was needed (for selects). Still, this would be a good exercise for
me, at least so I can figure out how to generate extraction functions.
> From: Tom Pledger [mailto:Tom.Pledger@peace.com]
> Here's one approach: find the OCI equivalent of JDBC's
> ResultSetMetaData, and use it to drive the allocation and freeing of
> buffers.
I've considered this, and I think it's the next route I'll take (the OCI
supports it). At the least it'll give me the ability to perform arbitrary
queries (at present I have to know the types of the result set columns and
construct the extraction function manually).
I've also considered stuffing more information into the Cursor type (which
I've introduced), and using this in a modal fashion to decide what to do at
each point.
> Here's another: ...
> Make getInt (and friends) behave differently depending on the mode
> of the cursor they're passed: either allocate a buffer and return
> _|_, decode and return the current column of the current row, or
> free a buffer and return _|_.
Not wanting to sound too dumb, but how do you return _|_ ?
Thanks,
Alistair.
*****************************************************************
The information in this email and in any attachments is
confidential and intended solely for the attention and use
of the named addressee(s). This information may be
subject to legal professional or other privilege or may
otherwise be protected by work product immunity or other
legal rules. It must not be disclosed to any person without
our authority.
If you are not the intended recipient, or a person
responsible for delivering it to the intended recipient, you
are not authorised to and must not disclose, copy,
distribute, or retain this message or any part of it.
*****************************************************************
From Keith.Wansbrough at cl.cam.ac.uk Wed Sep 24 12:11:44 2003
From: Keith.Wansbrough at cl.cam.ac.uk (Keith Wansbrough)
Date: Wed Sep 24 06:12:10 2003
Subject: Database interface - would like advice on oracle library
bind ing
In-Reply-To: Your message of "Wed, 24 Sep 2003 10:44:16 BST."
<7DFF3BC6CA957441AEADA7F340BFAA3401B33749@GBLONEX11.lon.invesco.com>
Message-ID:
> > Here's another: ...
> > Make getInt (and friends) behave differently depending on the mode
> > of the cursor they're passed: either allocate a buffer and return
> > _|_, decode and return the current column of the current row, or
> > free a buffer and return _|_.
>
> Not wanting to sound too dumb, but how do you return _|_ ?
Return
undefined
or better,
error "Erroneously demanded bottom result of buffer allocation phase"
Note that
undefined :: a
undefined = undefined
error :: String -> a
{- defined internally -}
HTH.
--KW 8-)
--
Keith Wansbrough
http://www.cl.cam.ac.uk/users/kw217/
University of Cambridge Computer Laboratory.
From brandon at its.caltech.edu Wed Sep 24 15:22:18 2003
From: brandon at its.caltech.edu (Brandon Michael Moore)
Date: Wed Sep 24 17:22:22 2003
Subject: Modeling multiple inheritance
Message-ID:
I'm trying to build a nicer interface over the one generated by
jvm-bridge. I'm using fancy type classes to remove the need to mangle
method names. I would like methods to be automatcially inherited,
following an inheritance hierarcy defined with another set of type
classes.
My basic classes look like this
class HasFooMethod cls args result | cls args -> result where
foo :: cls -> args -> result
If I have classes A and B with foo methods like
foo_JA_Jint :: ClassA -> Jint -> Bool
foo_JB_Jboolean :: ClassB -> Bool -> Jint
then I can make instances
instance HasFooMethod ClassA Jint Bool
instance HasFooMethod ClassB Bool Jint
Now I can just use foo everywhere. I would like to avoid declaring an
instance for every class though. In java methods are inherited from a
superclass, and I would like to inherit methods automatically as well. In
the bindings jvm-bridge generates a method is invoked with a function
mangled after the highest ancestor that defined that particular
overloading, so the implementation of HasFooMethod at a particular
overloading is the same for any descendant.
So I defined a class to model the inheritance relationships
class SubType super sub | sub -> super where
upCast :: sub -> super
Now I can define a default instance of HasFooMethod:
instance (HasFooMethod super args result,
SubClass super sub) =>
HasFooMethod sub args result where
foo sub args = foo (upCast sub) args
This will propagate foo methods down the inheritance hierarcy. If a new
class C is derived from A, I just need to say
instance SubClass ClassA ClassC
and ClassC gets a foo method. (In the actually code I piggy-back on a
transitive subclass relation jvm-bridge defines that already includes an
upcast method, so upCast has a default that should always be acceptable).
The problem comes when interfaces are added to the mix. Interfaces are
treated just like classes by jvm-bridge, and even though no implementation
is inherited from instances in Java, the method accessors generated by
jvm-bridge should be inherited.
One problem is that the subclass relationship needs the functional
dependency so that the default instance of HasFooMethod will respects the
functional dependencies of HasFooMethod, so I can't declare subclass
instances for multiple inheritance. On the other hand, if I don't use the
functional dependency on HasFooMethod I end up needing to annotate most of
the return values in a program. I run into similar problems trying to use
numeric literals as arguments, because they are also overloaded.
Does anyone know of clever solutions that would model multiple inheritance
while preserving the functional dependencies (unsafe compiler flags are
fine too), or ways to reduce the pain of overloading resolution without
the functional dependency?
One alternative is generating seperate HasFooMethod instances for every
class in the system. The problem is that this would require alterating the
bit of jvm-bridge that uses JNI to find information on classes, which
currently only reports newly defined methods. JNI is black magic to me.
Thanks
Brandon
From brandon at its.caltech.edu Wed Sep 24 20:02:32 2003
From: brandon at its.caltech.edu (Brandon Michael Moore)
Date: Wed Sep 24 22:02:36 2003
Subject: Modeling multiple inheritance
In-Reply-To:
References:
Message-ID:
On Thu, 25 Sep 2003 ozone@algorithm.com.au wrote:
> On 25/09/2003, at 7:22 AM, Brandon Michael Moore wrote:
>
> > I'm trying to build a nicer interface over the one generated by
> > jvm-bridge. I'm using fancy type classes to remove the need to mangle
> > method names. I would like methods to be automatcially inherited,
> > following an inheritance hierarcy defined with another set of type
> > classes.
> ...
>
> Hi Brandon, it looks like the way that you're modelling inheritance and
> OO-style overloading is basically the same way that I did in my thesis:
>
> http://www.algorithm.com.au/mocha
>
> The actual implementation of the thesis will be up in CVS in ~24 hours,
> I'm just waiting from an email back from the people I'm getting it
> hosted with.
>
> If you want a quick run-down on how I did the OO-style overloading
> without delving into the paper, let me know and I'll post a quick
> summary. I've only skimmed your email, but I think that the problem
> you're having with interfaces is solved with the way I'm modelling OO
> overloading and class inheritance.
Thanks. I think I could use the summary. I already found and skimmed your
thesis, and I don't think it gives me exactly what I want. All you do in
chapter 3 is represent a multiple inheritance hierarcy. I want default
instances that will propagate method definitions along the hierarcy. I'm
not sure that's possible though.
I want something like this:
data Object
data ClassA
data ClassB
data ClassC
class SubClass super sub ??>
instance SubClass Object ClassA
instance SubClass Object ClassB
instance SubClass ClassA ClassC
instance SubClass ClassB ClassC
class HasFooMethod cls args result ?>
foo :: cls -> args -> result
instance SubClass super sub, HasFooMethod super args result ,???
=> HasFooMethod sub args result where
foo obj args = foo (upCast obj) args
instance HasFooMethod Object int int where
foo = id
(now all four classes have a foo method)
Brandon
From simonpj at microsoft.com Thu Sep 25 09:19:26 2003
From: simonpj at microsoft.com (Simon Peyton-Jones)
Date: Thu Sep 25 03:19:30 2003
Subject: Modeling multiple inheritance
Message-ID: <4B93206CA3C55D4F96A61C9B1DC80DE350CA0B@EUR-MSG-03.europe.corp.microsoft.com>
When Mark Shields and I tackled this problem we came up with
Object-Oriented Style Overloading for Haskell
http://research.microsoft.com/~simonpj/Papers/oo-haskell/index.htm
It describes an (unimplemented) extension to Haskell, rather than
modelling it in Haskell itself, but you may find it interesting none the
less.
Simon
| -----Original Message-----
| From: haskell-cafe-bounces@haskell.org
[mailto:haskell-cafe-bounces@haskell.org] On Behalf Of
| Brandon Michael Moore
| Sent: 24 September 2003 22:22
| To: haskell-cafe@haskell.org
| Subject: Modeling multiple inheritance
|
| I'm trying to build a nicer interface over the one generated by
| jvm-bridge. I'm using fancy type classes to remove the need to mangle
| method names. I would like methods to be automatcially inherited,
| following an inheritance hierarcy defined with another set of type
| classes.
|
| My basic classes look like this
| class HasFooMethod cls args result | cls args -> result where
| foo :: cls -> args -> result
|
| If I have classes A and B with foo methods like
| foo_JA_Jint :: ClassA -> Jint -> Bool
| foo_JB_Jboolean :: ClassB -> Bool -> Jint
| then I can make instances
| instance HasFooMethod ClassA Jint Bool
| instance HasFooMethod ClassB Bool Jint
|
| Now I can just use foo everywhere. I would like to avoid declaring an
| instance for every class though. In java methods are inherited from a
| superclass, and I would like to inherit methods automatically as well.
In
| the bindings jvm-bridge generates a method is invoked with a function
| mangled after the highest ancestor that defined that particular
| overloading, so the implementation of HasFooMethod at a particular
| overloading is the same for any descendant.
|
| So I defined a class to model the inheritance relationships
|
| class SubType super sub | sub -> super where
| upCast :: sub -> super
|
| Now I can define a default instance of HasFooMethod:
| instance (HasFooMethod super args result,
| SubClass super sub) =>
| HasFooMethod sub args result where
| foo sub args = foo (upCast sub) args
|
| This will propagate foo methods down the inheritance hierarcy. If a
new
| class C is derived from A, I just need to say
|
| instance SubClass ClassA ClassC
|
| and ClassC gets a foo method. (In the actually code I piggy-back on a
| transitive subclass relation jvm-bridge defines that already includes
an
| upcast method, so upCast has a default that should always be
acceptable).
|
| The problem comes when interfaces are added to the mix. Interfaces are
| treated just like classes by jvm-bridge, and even though no
implementation
| is inherited from instances in Java, the method accessors generated by
| jvm-bridge should be inherited.
|
| One problem is that the subclass relationship needs the functional
| dependency so that the default instance of HasFooMethod will respects
the
| functional dependencies of HasFooMethod, so I can't declare subclass
| instances for multiple inheritance. On the other hand, if I don't use
the
| functional dependency on HasFooMethod I end up needing to annotate
most of
| the return values in a program. I run into similar problems trying to
use
| numeric literals as arguments, because they are also overloaded.
|
| Does anyone know of clever solutions that would model multiple
inheritance
| while preserving the functional dependencies (unsafe compiler flags
are
| fine too), or ways to reduce the pain of overloading resolution
without
| the functional dependency?
|
| One alternative is generating seperate HasFooMethod instances for
every
| class in the system. The problem is that this would require alterating
the
| bit of jvm-bridge that uses JNI to find information on classes, which
| currently only reports newly defined methods. JNI is black magic to
me.
|
| Thanks
| Brandon
|
| _______________________________________________
| Haskell-Cafe mailing list
| Haskell-Cafe@haskell.org
| http://www.haskell.org/mailman/listinfo/haskell-cafe
From simons at cryp.to Tue Sep 23 17:26:42 2003
From: simons at cryp.to (Peter Simons)
Date: Thu Sep 25 06:57:58 2003
Subject: Generating "setMember" functions for record structures
In-Reply-To:
References: <87wubzr6wk.fsf@peti.cryp.to>
Message-ID: <87fzinr36l.fsf@peti.cryp.to>
Peter Gammie writes:
> Haskell Report, Sec 3.15.3
Great, that's exactly what I need.
Thanks a lot to all who replied!
Peter
From ozone at algorithm.com.au Thu Sep 25 12:21:59 2003
From: ozone at algorithm.com.au (ozone@algorithm.com.au)
Date: Thu Sep 25 06:57:59 2003
Subject: Modeling multiple inheritance
In-Reply-To:
References:
Message-ID:
On 25/09/2003, at 7:22 AM, Brandon Michael Moore wrote:
> I'm trying to build a nicer interface over the one generated by
> jvm-bridge. I'm using fancy type classes to remove the need to mangle
> method names. I would like methods to be automatcially inherited,
> following an inheritance hierarcy defined with another set of type
> classes.
...
Hi Brandon, it looks like the way that you're modelling inheritance and
OO-style overloading is basically the same way that I did in my thesis:
http://www.algorithm.com.au/mocha
The actual implementation of the thesis will be up in CVS in ~24 hours,
I'm just waiting from an email back from the people I'm getting it
hosted with.
If you want a quick run-down on how I did the OO-style overloading
without delving into the paper, let me know and I'll post a quick
summary. I've only skimmed your email, but I think that the problem
you're having with interfaces is solved with the way I'm modelling OO
overloading and class inheritance.
--
% Andre Pang : trust.in.love.to.save
From oleg at pobox.com Wed Sep 24 21:20:00 2003
From: oleg at pobox.com (oleg@pobox.com)
Date: Thu Sep 25 06:58:00 2003
Subject: Database interface - would like advice on oracle library binding
In-Reply-To:
<7DFF3BC6CA957441AEADA7F340BFAA3401B33749@GBLONEX11.lon.invesco.com>
Message-ID: <200309250320.h8P3K0mh025061@adric.fnmoc.navy.mil>
The following code illustrates a _generic_ interface to low-level
database code. The left-fold iterator doQuery is completely generic
over any possible iterator -- no matter how many columns the query
returns, what are the types of these columns and what is the type of
the seed (accumulator). The code for doQuery remains the same. The
iterator allocates buffers for columns at the beginning and frees the
buffers at the very end. Again, this buffer handling is generic. There
is no longer need to write extraction/unmarshalling function for
specific types of rows. We only need fetching functions for specific
datatypes (not columns!). Again, the query and the row buffer
management code is completely generic. I guess I'm repeating
myself. The tests:
-- Query returns one column of type String
-- Never mind undefined: we return some static data in the buffers,
-- we don't have any oracle to bind to
test1 = doQuery undefined undefined iter1 ([]::[String])
where
iter1:: String -> [String] -> Either [String] [String]
iter1 s acc = Right $ s:acc
-- Query returns two columns of types String and Int
test2 = doQuery undefined undefined iter2 ([]::[(String,Int)])
where
iter2:: String -> Int -> [(String,Int)] ->
Either [(String,Int)] [(String,Int)]
iter2 s i acc = Right $ (s,i):acc
-- Query returns three columns of types Int, String and Int
test3 = doQuery undefined undefined iter3 ([]::[(Int,String,Int)])
where
iter3:: Int -> String -> Int -> [(Int,String,Int)] ->
Either [(Int,String,Int)] [(Int,String,Int)]
iter3 i1 s i2 acc = Right $ (i1,s,i2):acc
Use the function runtests to run either of these tests.
The code follows. Compiler flags:
-fglasgow-exts -fallow-overlapping-instances
-- DB column buffers
type BufferSize = Int
data BufferType = ORA_char | ORA_int
type Position = Int -- column number of the result table
data Buffer = Buffer { bufptr :: String -- for this stub, just use String
, nullindptr :: String -- likewise
, retsizeptr :: String -- likewise
, size:: BufferSize
, pos:: Position
, ora_type:: BufferType }
-- understandably, below is just a stub ...
alloc_buffer (siz, typ) ps =
return $ Buffer { bufptr = show ps, pos = ps, size = siz, ora_type = typ}
-- In this stub, don't do anything
free ptr = return ()
-- DB Column types
class DBType a where
alloc_buffer_hints:: a -> (BufferSize, BufferType)
col_fetch:: Buffer -> IO a
instance DBType String where
alloc_buffer_hints _ = (2000, ORA_char)
col_fetch buffer = return (bufptr buffer)
instance DBType Int where
alloc_buffer_hints _ = (4, ORA_int)
col_fetch buffer = return (read $ bufptr buffer)
-- need to add more ...
-- Row iteratees. Note, the folowing two instances cover ALL possible
-- iteratees. No other instances are needed
class SQLIteratee iter seed where
iter_apply:: [Buffer] -> seed -> iter -> IO (Either seed seed)
alloc_buffers:: Position -> iter -> seed -> IO [Buffer]
instance (DBType a) => SQLIteratee (a->seed->Either seed seed) seed where
iter_apply [buf] seed fn = col_fetch buf >>= (\v -> return$ fn v seed)
alloc_buffers n _ _ =
sequence [alloc_buffer (alloc_buffer_hints (undefined::a)) n]
instance (SQLIteratee iter' seed, DBType a) => SQLIteratee (a->iter') seed
where
iter_apply (buf:others) seed fn =
col_fetch buf >>= (\v -> iter_apply others seed (fn v))
alloc_buffers n fn seed = do
this_buffer <- alloc_buffer (alloc_buffer_hints (undefined::a)) n
other_buffers <- alloc_buffers (n+1) (fn (undefined::a)) seed
return (this_buffer:other_buffers)
free_buffers = mapM_ free
-- The left fold iterator -- the query executor
data Session -- not relevant for this example
data SQLStmt
db_execute session query = return ()
db_fetch_row buffers = return () -- use static data
doQuery:: (SQLIteratee iter seed) => Session -> SQLStmt -> iter -> seed -> IO seed
-- In this example, we just allocate buffers, "fetch" two rows and terminate
-- with a clean-up
doQuery session query iteratee seed = do
buffers <- alloc_buffers 0 iteratee seed
db_execute session query
db_fetch_row buffers
(Right seed) <- iter_apply buffers seed iteratee
db_fetch_row buffers
(Right seed) <- iter_apply buffers seed iteratee
free_buffers buffers
return seed
-- Tests
-- Query returns one column of type String
test1 = doQuery undefined undefined iter1 ([]::[String])
where
iter1:: String -> [String] -> Either [String] [String]
iter1 s acc = Right $ s:acc
-- Query returns two columns of types String and Int
test2 = doQuery undefined undefined iter2 ([]::[(String,Int)])
where
iter2:: String -> Int -> [(String,Int)] ->
Either [(String,Int)] [(String,Int)]
iter2 s i acc = Right $ (s,i):acc
-- Query returns three columns of types Int, String and Int
test3 = doQuery undefined undefined iter3 ([]::[(Int,String,Int)])
where
iter3:: Int -> String -> Int -> [(Int,String,Int)] ->
Either [(Int,String,Int)] [(Int,String,Int)]
iter3 i1 s i2 acc = Right $ (i1,s,i2):acc
runtests test = test >>= (mapM_ $ putStrLn . show)
From list at taesch.com Thu Sep 25 16:55:29 2003
From: list at taesch.com (Luc Taesch)
Date: Thu Sep 25 08:55:32 2003
Subject: Haskell as specification language
Message-ID: <200309251255.h8PCtO93011368@fury.vortech.net>
out of curiosity, is haskell already been used as a "specification" language ?
i was thinking in a business term, rather than mathematical one. (i.e. one than " normal mortal can read, even with a bit of training ;-)
I.e. one would specifiy a model, an application ( possibly run it on samples), and hand it over to
developper, typically in other languages/environment...
I am aware of the contracts paper of SPJ, for instance... others you may think of ?
does a spec. always leads to a DSL , for instance ?
I imagine a specification for an application resulting in a DSL for the "data model"/ " process model " part, (which is the generic/ reusabel part, IMH) plus something more specific to the effective application targeted...
(I cannot resist explaining my long term view : if IT outsourcing really takes off one day, one key factor will be proper specification, which is in a dear state in the current practice nowadays "in the field")
ref: http://search.ft.com/search/article.html?id=030923007625
From brandon at its.caltech.edu Thu Sep 25 14:25:26 2003
From: brandon at its.caltech.edu (Brandon Michael Moore)
Date: Thu Sep 25 16:25:30 2003
Subject: lexer puzzle
In-Reply-To: <001101c38388$85f3e390$1e02a8c0@Sean>
References: <9D83635E-E77C-11D7-9A3E-000393D3FD08@cs.uu.nl><200309240044.32206.qrczak@knm.org.pl>
<3F722BEA.2090805@cse.ogi.edu> <001101c38388$85f3e390$1e02a8c0@Sean>
Message-ID:
Note I've replied to haskell-cafe. This post is a bit chatty and low on
solid answers.
On Thu, 25 Sep 2003, Sean L. Palmer wrote:
> > >>A... should be split into "A.." and "."
> > >I found a compromise: let's make it a lexing error! :-)
> > At least that agrees with what some Haskell compilers implement. No
> > current Haskell compiler/interpreter agrees with what the report seems
> > to say, that is that "A..." should be lexed as the two tokens "A.." and
> > ".", and similarly, "A.where" should be lexed as "A.wher" followed by "e".
>
> Hi. I'm really new to Haskell, just learning it, and I must say I'm pretty
> overwhelmed by the large variety of constructs. (=>, <-, \ to name a few)
Would that be \ as in TREX row variable polymorphism? Just remember most
operators are just library functions. It's only =, ->, =>, <-, :: that are
really part of the language, and {,},; for grouping. Did I miss any?
>
> But I'm just writing this to let you guys know (surely you know this
> already) that anyone from a C/C++/Java/Delphi background is going to
> completely misunderstand the meaning of A.anything in Haskell... it's
> completely nonintuitive to people with my background. I kinda like dot
> notation because it ties together the symbols visually, for instance
> "myrec.myfield" is more of a unit than "myrec myfield". It stays together
> better when surrounded by other code, and would result in fewer parenthesis
> necessary.
A Python programmer would understand instantly: Python uses exactly the
same syntax for module access, though Python modules are usually in
lowercase. It also seems to be very much in the spirit of "access a member
of this object" of an OO language.
Or was that supposed to be composition of a constructor with a function, A
. f? Function composition, and higher order functions in general are
likely to confuse an imperative programmer, but I think there isn't much
syntax can do there.
Or are you talking about the field access syntax? Maybe the problem is
that dot has two to five different meanings, function composition, naming
module members, building hierarchial module names, being a decimal point,
and making elipses, and is commonly used for yet another purpose in OO
languages.
> Haskell to me seems to be a great language with a syntax problem, and a bad
> case of too many ways to do the same thing; thus every programmer does
> things their own way and it's difficult to grasp the language by looking at
> various programs, since they're all so very different. As a small example,
> there's 'let' vs. 'where'. Maybe a bit of pruning would be in order.
Do you mean the syntax is bad in places? Haskell is the cleanest language
I know of, but I'm sure it has some grungy bits. I've had problems with
unary minus (can't slice binary minus), and precedence of with irrefuatble
patterns and type ascription. I would be happy for any confusing syntax to
be improved. Any good ideas? Syntax change is a possibility: do notation
is a relatively recent addition, and arrow syntax is in the works.
I think you might instead mean the syntax cuts down our market share
because it isn't like common (C derived) languages. I don't think Haskell
could borrow any more syntax from C without actually making the language
worse. It's a problem, but not with the syntax. If someone is so solidly
into a C++/Java/OO mindset that the syntax would be a problem, the
semantics would probably be even more of a problem.
I would suggest Python if Haskell was too much of a jump for someone. It's
still OO, but it encourages more flexible and interesting programs, and
you don't have to live in a Java type system. Plus, it has more libraries,
bindings, and PR, so it's easier to get permission to use it in a company.
If someone is used to Python's layout rule and lack of type signatures,
and gets their head around some of the fun you can have dynamically
picking which members of an object to access, assigning to __dict__ and so
on, then Haskell should be much less of a jump in syntax, and less
imposing in semantics.
> That said, I still think it looks more promising than any other language
> I've looked at that actually is being actively used and maintained and has a
> decent installed base and good cross platform support. So I will learn it.
> I just wish the transition was easier and that it took less time to learn.
> ;)
>
> Sean
I learned Haskell from the "gentle introduction". It seemed gentle enough
to me but others disagree, so I'm probably not the best for advice for the
raw beginner. If you are interested in learning about monads though,
Jeff Newbern's monad tutorial seems accessible and as complete as anything
this side of Phil Wadler's paper.
I hope learning Haskell goes well.
Brandon
From oleg at pobox.com Thu Sep 25 20:20:02 2003
From: oleg at pobox.com (oleg@pobox.com)
Date: Thu Sep 25 22:20:24 2003
Subject: Modeling multiple inheritance
In-Reply-To:
Message-ID: <200309260220.h8Q2K2vZ026705@adric.fnmoc.navy.mil>
Brandon Michael Moore wrote:
> So I defined a class to model the inheritance relationships
> class SubType super sub | sub -> super where
> upCast :: sub -> super
> Now I can define a default instance of HasFooMethod:
> instance (HasFooMethod super args result,
> SubClass super sub) =>
> HasFooMethod sub args result where
> foo sub args = foo (upCast sub) args
> This will propagate foo methods down the inheritance hierarcy. If a new
> class C is derived from A, I just need to say
> One problem is that the subclass relationship needs the functional
> dependency
> Does anyone know of clever solutions that would model multiple inheritance
> while preserving the functional dependencies (unsafe compiler flags are
> fine too), or ways to reduce the pain of overloading resolution without
> the functional dependency?
Yes. The code included. The solution is trivial: in case of a multiple
inheritance, a class has a _sequence_ of superclasses rather than a
single superclass. Like
instance SubClass (Object,()) ClassA
instance SubClass (Object,()) ClassB
-- Multiple inheritance (including the diamond!)
instance SubClass (ClassA,(ClassB,())) ClassC
instance SubClass (ClassA,(ClassB,(ClassC,()))) ClassD
And we need some intelligence to traverse the sequence. But even a
computer can do that.
I would like to propose a different solution: a dual of
typeclasses in the value domain. Function foo is just a regular
function
foo:: Object -> Int -> Int
foo x y = y
We then need a class MApplicable fn args result with a method
mapply. The trick is that the method should take any object of a type
castable and cast it to the type of the first argument of fn. The cast
can be made safe and statically checkable, using the type
heap. Actually, we can use the type heap to model the dispatch table
(whose rows are functions and columns are object/classes). Given a
function and an object, we can search in many way for the applicable
combination.
And now, the code for the solution that works.
Compiler flags:
-fglasgow-exts -fallow-overlapping-instances -fallow-undecidable-instances
data Object = Object
data ClassA = ClassA
data ClassB = ClassB
data ClassC = ClassC
data ClassD = ClassD
class SubClass super sub | sub -> super where
upCast :: sub -> super
instance SubClass (Object,()) ClassA
instance SubClass (Object,()) ClassB
-- Multiple inheritance (including the diamond!)
instance SubClass (ClassA,(ClassB,())) ClassC
instance SubClass (ClassA,(ClassB,(ClassC,()))) ClassD
class HasFooMethod cls args result where
foo :: cls -> args -> result
instance (SubClass supers sub,
HasFooMethod supers args result)
=> HasFooMethod sub args result where
foo obj args = foo (upCast obj) args
instance (HasFooMethod cls args result) => HasFooMethod (cls,()) args result
where
foo (x,()) = foo x
instance (HasFooMethod cls args result) => HasFooMethod (x,cls) args result
where
foo (x,y) = foo y
instance HasFooMethod Object Int Int where
foo _ x = x
test1::Int = foo Object (1::Int)
test2::Int = foo ClassA (2::Int)
test3::Int = foo ClassD (3::Int)
-- Likewise for another method:
class HasBarMethod cls args result where
bar :: cls -> args -> result
instance (SubClass supers sub,
HasBarMethod supers args result)
=> HasBarMethod sub args result where
bar obj args = bar (upCast obj) args
instance (HasBarMethod cls args result) => HasBarMethod (cls,()) args result
where
bar (x,()) = bar x
instance (HasBarMethod cls args result) => HasBarMethod (x,cls) args result
where
bar (x,y) = bar y
instance HasBarMethod ClassB Bool Bool where
bar _ x = x
test4::Bool = bar ClassB True
test5::Bool = bar ClassC True
test6::Bool = bar ClassD True
From ketil at ii.uib.no Fri Sep 26 09:59:12 2003
From: ketil at ii.uib.no (Ketil Z. Malde)
Date: Fri Sep 26 02:59:17 2003
Subject: lexer puzzle
In-Reply-To:
References: <9D83635E-E77C-11D7-9A3E-000393D3FD08@cs.uu.nl>
<200309240044.32206.qrczak@knm.org.pl> <3F722BEA.2090805@cse.ogi.edu>
<001101c38388$85f3e390$1e02a8c0@Sean>
Message-ID:
Brandon Michael Moore writes:
> Or was that supposed to be composition of a constructor with a function, A
> . f? Function composition, and higher order functions in general are
> likely to confuse an imperative programmer, but I think there isn't much
> syntax can do there.
I think there is a problem with too much overloaded syntax. Perhaps
it is time to put non-ASCII characters to good use?
For instance, function composition could use the degree sign: ?
and leave the . for module qualification.
Template Haskell could use double-angle quotation marks: ? ?
and the section sign: ?
and avoid clashing with list comprehensions and the function
application operator.
Implicit parameters could use an inverted question mark: ?
And so on, just look for places where the semantics depend on spaces
in the right (or wrong) place.
-kzm
--
If I haven't seen further, it is by standing in the footprints of giants
From john at repetae.net Fri Sep 26 01:16:55 2003
From: john at repetae.net (John Meacham)
Date: Fri Sep 26 03:16:59 2003
Subject: lexer puzzle
In-Reply-To:
References: <9D83635E-E77C-11D7-9A3E-000393D3FD08@cs.uu.nl>
<200309240044.32206.qrczak@knm.org.pl> <3F722BEA.2090805@cse.ogi.edu>
<001101c38388$85f3e390$1e02a8c0@Sean>
Message-ID: <20030926071655.GA3520@momenergy.repetae.net>
On Fri, Sep 26, 2003 at 08:59:12AM +0200, Ketil Z. Malde wrote:
> Brandon Michael Moore writes:
>
> > Or was that supposed to be composition of a constructor with a function, A
> > . f? Function composition, and higher order functions in general are
> > likely to confuse an imperative programmer, but I think there isn't much
> > syntax can do there.
>
> I think there is a problem with too much overloaded syntax. Perhaps
> it is time to put non-ASCII characters to good use?
>
> For instance, function composition could use the degree sign: ?
> and leave the . for module qualification.
why not the actual functional composition operator: ? or ?
we could also make good use of ? ? ? ? ? ? and all the other fun
mathematical operators.
>
> Template Haskell could use double-angle quotation marks: ? ?
> and the section sign: ?
> and avoid clashing with list comprehensions and the function
> application operator.
>
> Implicit parameters could use an inverted question mark: ?
>
> And so on, just look for places where the semantics depend on spaces
> in the right (or wrong) place.
I would love to be able to use unicode to make my programs more
readable. just as an alternate syntax for awkward ascii constructs.
and as operator, function names when they make sense.
this could probably be done with a preprocessor, but wolud be easier in
the compiler to work out the layout rule and handle language extensions
and whatnot.
John
--
---------------------------------------------------------------------------
John Meacham - California Institute of Technology, Alum. - john@foo.net
---------------------------------------------------------------------------
From ketil at ii.uib.no Fri Sep 26 10:56:40 2003
From: ketil at ii.uib.no (Ketil Z. Malde)
Date: Fri Sep 26 03:56:50 2003
Subject: lexer puzzle
In-Reply-To: <20030926071655.GA3520@momenergy.repetae.net>
References: <9D83635E-E77C-11D7-9A3E-000393D3FD08@cs.uu.nl>
<200309240044.32206.qrczak@knm.org.pl> <3F722BEA.2090805@cse.ogi.edu>
<001101c38388$85f3e390$1e02a8c0@Sean>
<20030926071655.GA3520@momenergy.repetae.net>
Message-ID:
John Meacham writes:
>> For instance, function composition could use the degree sign: ?
>> and leave the . for module qualification.
> why not the actual functional composition operator: ? or ?
Because: a) I've always used a small circle, the centered dot is for
(dot) products. I guess this is just a matter of mathematical
dialects. And
b) I didn't find it :-)
-------------- next part --------------
> we could also make good use of $B"O(B $B"P(B $B"M(B $B"+(B $B"J(B $B"K(B and all the other fun
> mathematical operators.
Cool! However, I think most/some current tools use ISO-8859(-1 or
whatever) input, and for legacy reasons it may be a good idea to stick
to symbols in that (those) subset(s).
As you may have noticed, I suggested mostly these symbols for
the language extensions, keeping H98 in 7 bits may or may not be a
priority. At any rate, extensions could probably more easily
disregrard legacy.
> I would love to be able to use unicode to make my programs more
> readable. just as an alternate syntax for awkward ascii constructs.
> and as operator, function names when they make sense.
Another thing; it should be possible to have (X)Emacs use display the
glyphs you mention ($B"O(B $B"P(B $B"M(B $B"+(B $B"J(B $B"K(B) instead of the underlying
multigraphs.
> this could probably be done with a preprocessor, but wolud be easier in
> the compiler to work out the layout rule and handle language extensions
> and whatnot.
Layout may be a problem. Not for type signatures, though.
-kzm
--
If I haven't seen further, it is by standing in the footprints of giants
From Keith.Wansbrough at cl.cam.ac.uk Fri Sep 26 12:08:27 2003
From: Keith.Wansbrough at cl.cam.ac.uk (Keith Wansbrough)
Date: Fri Sep 26 06:08:34 2003
Subject: lexer puzzle
In-Reply-To: Your message of "Thu, 25 Sep 2003 13:25:26 PDT."
Message-ID:
> > Hi. I'm really new to Haskell, just learning it, and I must say I'm pretty
> > overwhelmed by the large variety of constructs. (=>, <-, \ to name a few)
>
> Would that be \ as in TREX row variable polymorphism? Just remember most
> operators are just library functions. It's only =, ->, =>, <-, :: that are
> really part of the language, and {,},; for grouping. Did I miss any?
Yes, you missed \, which is used for function abstraction:
(\x -> x*x) 3
And ( , ) for tuples.
And I don't think "->" is part of the language - it only appears in the type syntax, not term syntax. If you allow it, you have to allow * as well.
--KW 8-)
--
Keith Wansbrough
http://www.cl.cam.ac.uk/users/kw217/
University of Cambridge Computer Laboratory.
From Malcolm.Wallace at cs.york.ac.uk Fri Sep 26 12:12:58 2003
From: Malcolm.Wallace at cs.york.ac.uk (Malcolm Wallace)
Date: Fri Sep 26 06:15:12 2003
Subject: lexer puzzle
In-Reply-To:
References:
Message-ID: <20030926111258.6bbde80f.Malcolm.Wallace@cs.york.ac.uk>
Keith Wansbrough writes:
>
> And I don't think "->" is part of the language - it only appears in the type
> syntax, not term syntax. If you allow it, you have to allow * as well.
Errm, you just gave an example of -> in the term syntax...
> (\x -> x*x) 3
Regards,
Malcolm
From Keith.Wansbrough at cl.cam.ac.uk Fri Sep 26 12:17:08 2003
From: Keith.Wansbrough at cl.cam.ac.uk (Keith Wansbrough)
Date: Fri Sep 26 06:17:14 2003
Subject: lexer puzzle
In-Reply-To: Your message of "Fri, 26 Sep 2003 11:12:58 BST."
<20030926111258.6bbde80f.Malcolm.Wallace@cs.york.ac.uk>
Message-ID:
> Keith Wansbrough writes:
> >
> > And I don't think "->" is part of the language - it only appears in the type
> > syntax, not term syntax. If you allow it, you have to allow * as well.
>
> Errm, you just gave an example of -> in the term syntax...
>
> > (\x -> x*x) 3
Guilty... sorry! :-(
--KW 8-)
--
Keith Wansbrough
http://www.cl.cam.ac.uk/users/kw217/
University of Cambridge Computer Laboratory.
From franka at cs.uu.nl Fri Sep 26 15:13:26 2003
From: franka at cs.uu.nl (Frank Atanassow)
Date: Fri Sep 26 08:13:30 2003
Subject: lexer puzzle
In-Reply-To: <20030926071655.GA3520@momenergy.repetae.net>
Message-ID:
On vrijdag, sep 26, 2003, at 09:16 Europe/Amsterdam, John Meacham wrote:
> On Fri, Sep 26, 2003 at 08:59:12AM +0200, Ketil Z. Malde wrote:
>> I think there is a problem with too much overloaded syntax. Perhaps
>> it is time to put non-ASCII characters to good use?
>>
>> For instance, function composition could use the degree sign: ?
>> and leave the . for module qualification.
>
> why not the actual functional composition operator: ? or ?
>
> we could also make good use of ? ? ? ? ? ? and all the other fun
> mathematical operators.
This is very readable, but not very writable.
Until I get a keyboard with a ? key, I would prefer to restrict the
syntax to ASCII/whatever and simply make it the editor's responsibility
to display source code using special characters.
??????
From brandon at its.caltech.edu Fri Sep 26 13:57:04 2003
From: brandon at its.caltech.edu (Brandon Michael Moore)
Date: Fri Sep 26 15:57:10 2003
Subject: Modeling multiple inheritance
In-Reply-To: <200309260220.h8Q2K2vZ026705@adric.fnmoc.navy.mil>
References: <200309260220.h8Q2K2vZ026705@adric.fnmoc.navy.mil>
Message-ID:
On Thu, 25 Sep 2003 oleg@pobox.com wrote:
>
> Brandon Michael Moore wrote:
>
> > So I defined a class to model the inheritance relationships
>
> > class SubType super sub | sub -> super where
> > upCast :: sub -> super
>
> > Now I can define a default instance of HasFooMethod:
> > instance (HasFooMethod super args result,
> > SubClass super sub) =>
> > HasFooMethod sub args result where
> > foo sub args = foo (upCast sub) args
>
> > This will propagate foo methods down the inheritance hierarcy. If a new
> > class C is derived from A, I just need to say
>
> > One problem is that the subclass relationship needs the functional
> > dependency
>
> > Does anyone know of clever solutions that would model multiple inheritance
> > while preserving the functional dependencies (unsafe compiler flags are
> > fine too), or ways to reduce the pain of overloading resolution without
> > the functional dependency?
>
> Yes. The code included. The solution is trivial: in case of a multiple
> inheritance, a class has a _sequence_ of superclasses rather than a
> single superclass. Like
>
> instance SubClass (Object,()) ClassA
> instance SubClass (Object,()) ClassB
>
> -- Multiple inheritance (including the diamond!)
> instance SubClass (ClassA,(ClassB,())) ClassC
> instance SubClass (ClassA,(ClassB,(ClassC,()))) ClassD
>
> And we need some intelligence to traverse the sequence. But even a
> computer can do that.
That should solve my problem. Putting all the superclasses in a tuple
should work. I'm worried about large class hierarchies. If it works on the
java.* classes I should be fine. Have you used this approach before? I'm
worried about compile time, runtime costs from the casts (hopefully they
compile out), and maybe exceeding maximum stack depth in context
reduction. This is a clever solution. I like it. Now, is anyone up to
encoding the Dylan MRO in Haskell type classes? ;)
> I would like to propose a different solution: a dual of
> typeclasses in the value domain. Function foo is just a regular
> function
>
> foo:: Object -> Int -> Int
> foo x y = y
>
> We then need a class MApplicable fn args result with a method
> mapply. The trick is that the method should take any object of a type
> castable and cast it to the type of the first argument of fn. The cast
> can be made safe and statically checkable, using the type
> heap. Actually, we can use the type heap to model the dispatch table
> (whose rows are functions and columns are object/classes). Given a
> function and an object, we can search in many way for the applicable
> combination.
What type heap? It sounds like you are talking about information from an
OO runtime, or are you talking about the collection of instances. I tried
a system where method names were also represented by data types, but
without your solution for multiple inheritance I couldn't get the
implementation inheritance I wanted. How would you implement this dispatch
table? What are the advantages of this approach over the type class
encoding? I'm worried that generating bindings would be a problem if the
dispatch table needs to be a monolithic value with a very interesting type
in some file.
Brandon
> And now, the code for the solution that works.
> Compiler flags:
> -fglasgow-exts -fallow-overlapping-instances -fallow-undecidable-instances
>
> data Object = Object
> data ClassA = ClassA
> data ClassB = ClassB
> data ClassC = ClassC
> data ClassD = ClassD
>
> class SubClass super sub | sub -> super where
> upCast :: sub -> super
>
> instance SubClass (Object,()) ClassA
> instance SubClass (Object,()) ClassB
> -- Multiple inheritance (including the diamond!)
> instance SubClass (ClassA,(ClassB,())) ClassC
> instance SubClass (ClassA,(ClassB,(ClassC,()))) ClassD
>
> class HasFooMethod cls args result where
> foo :: cls -> args -> result
>
> instance (SubClass supers sub,
> HasFooMethod supers args result)
> => HasFooMethod sub args result where
> foo obj args = foo (upCast obj) args
>
> instance (HasFooMethod cls args result) => HasFooMethod (cls,()) args result
> where
> foo (x,()) = foo x
>
> instance (HasFooMethod cls args result) => HasFooMethod (x,cls) args result
> where
> foo (x,y) = foo y
>
> instance HasFooMethod Object Int Int where
> foo _ x = x
>
> test1::Int = foo Object (1::Int)
> test2::Int = foo ClassA (2::Int)
> test3::Int = foo ClassD (3::Int)
>
> -- Likewise for another method:
>
> class HasBarMethod cls args result where
> bar :: cls -> args -> result
>
> instance (SubClass supers sub,
> HasBarMethod supers args result)
> => HasBarMethod sub args result where
> bar obj args = bar (upCast obj) args
>
> instance (HasBarMethod cls args result) => HasBarMethod (cls,()) args result
> where
> bar (x,()) = bar x
>
> instance (HasBarMethod cls args result) => HasBarMethod (x,cls) args result
> where
> bar (x,y) = bar y
>
> instance HasBarMethod ClassB Bool Bool where
> bar _ x = x
>
> test4::Bool = bar ClassB True
> test5::Bool = bar ClassC True
> test6::Bool = bar ClassD True
>
>
From oleg at pobox.com Fri Sep 26 21:19:29 2003
From: oleg at pobox.com (oleg@pobox.com)
Date: Fri Sep 26 23:19:53 2003
Subject: Modeling multiple inheritance
In-Reply-To:
References:
<200309260220.h8Q2K2vZ026705@adric.fnmoc.navy.mil>
Message-ID: <200309270319.h8R3JTmT028485@adric.fnmoc.navy.mil>
Brandon Michael Moore wrote regarding the first solution: chain of
super-classes:
> I'm worried about large class hierarchies. If it works on the
> java.* classes I should be fine. Have you used this approach before? I'm
> worried about compile time, runtime costs from the casts (hopefully they
> compile out), and maybe exceeding maximum stack depth in context
> reduction.
I didn't use the approach for anything as complex as all java.*
classes. The only run-time costs are evaluating the chain of fst . snd
. fst . .... The length and the composition of the chain is statically
known. Perhaps the compiler can do something smart here. The maximum
length of the chain is the maximum depth of the inheritance tree. It
shouldn't be too big. A cast from a subclass to a superclass has to be
executed anyway (if not by your code then by JVM). If the maximum
stack depth is exceeded, we can repeat the compilation with a compiler
flag to allocate a bigger stack. In my experience the only time I've
seen the derivation stack depth exceeded is when the derivation truly
diverges.
> What type heap? It sounds like you are talking about information from an
> OO runtime, or are you talking about the collection of instances.
The other solution I talked so confusingly before is that of generic
functions. For that, we need a way to obtain a value representation of a
type. Several such representations exists: e.g., Typable,
representation as an integer, etc. All our objects must be members of
the class Typable. A method (generic function foo) would have the
following signature:
foo:: (Typable object) => object -> Int ->Int
For example, if foo is defined for ClassA object only, we can write
foo obj arg =
if inherit_from (typeof obj) (typeof (undefined::ClassA))
then particular_instance_foo (coerce obj) arg
else error "miscast"
If bar is defined for classB and redefined in classC, we can write
bar obj arg =
if inherit_from (typeof obj) (typeof (undefined::ClassC))
then particular_instance1_bar (coerce obj) arg
else if inherit_from (typeof obj) (typeof (undefined::ClassB))
then particular_instance2_bar (coerce obj) arg
else error "miscast"
The functions inherit_from and coerce avail themselves of a table that
records the relationship between types using their value
representations.
The disadvantage of this approach is that the cast errors become
run-time errors. OTH, because type representations and the whole
inheritance graph are values, we can do much more. We can check for
proper and improper diamond inheritance, we can do a rather
sophisticated dispatch.
Types heap and several ways of doing safe casts are discussed in
http://www.haskell.org/pipermail/haskell/2003-August/012372.html
http://www.haskell.org/pipermail/haskell/2003-August/012355.html
See also:
http://citeseer.nj.nec.com/cheney02lightweight.html
http://citeseer.nj.nec.com/context/1670116/0
The Sketch of a Polymorphic Symphony
http://homepages.cwi.nl/~ralf/polymorphic-symphony/
From dominic.steinitz at blueyonder.co.uk Sat Sep 27 09:02:22 2003
From: dominic.steinitz at blueyonder.co.uk (Dominic Steinitz)
Date: Sat Sep 27 03:05:11 2003
Subject: (Off-topic) Question about categories
Message-ID: <000301c384c5$4c8defe0$1464a8c0@canterburysoftware.com>
Graham,
I'm not sure if anyone mentioned the examples of a poset and a monoid as
categories. There is no "internal" structure in these. In the former, the
objects are the elements and there is a morphism between a and b iff a <= b.
A functor then becomes an order preserving map. In the latter, there is one
object and the morphisms are the elements. The identity is the identity map
and if x and y are two elements / morphisms then composition is xy. A
functor is then a homomorphism.
Dominic.
From brandon at its.caltech.edu Sat Sep 27 03:25:38 2003
From: brandon at its.caltech.edu (Brandon Michael Moore)
Date: Sat Sep 27 05:25:42 2003
Subject: Modeling multiple inheritance
In-Reply-To: <200309270319.h8R3JTmT028485@adric.fnmoc.navy.mil>
References:
<200309260220.h8Q2K2vZ026705@adric.fnmoc.navy.mil>
<200309270319.h8R3JTmT028485@adric.fnmoc.navy.mil>
Message-ID:
On Fri, 26 Sep 2003 oleg@pobox.com wrote:
>
> Brandon Michael Moore wrote regarding the first solution: chain of
> super-classes:
>
> > I'm worried about large class hierarchies. If it works on the
> > java.* classes I should be fine. Have you used this approach before? I'm
> > worried about compile time, runtime costs from the casts (hopefully they
> > compile out), and maybe exceeding maximum stack depth in context
> > reduction.
>
> I didn't use the approach for anything as complex as all java.*
> classes. The only run-time costs are evaluating the chain of fst . snd
> . fst . ....
I think I can use the pair types as phantom types on a reference type, so
my casts will hopefully be the identity function. (.) should be small
enough to inline, so GHC probably compiles id . id ... id to id. Correct?
> The length and the composition of the chain is statically
> known. Perhaps the compiler can do something smart here. The maximum
> length of the chain is the maximum depth of the inheritance tree. It
> shouldn't be too big. A cast from a subclass to a superclass has to be
> executed anyway (if not by your code then by JVM). If the maximum
> stack depth is exceeded, we can repeat the compilation with a compiler
> flag to allocate a bigger stack. In my experience the only time I've
> seen the derivation stack depth exceeded is when the derivation truly
> diverges.
Same for me, but I've never tried to model the java.* hierarchy either. I
think you get a cast (fst in your code) for each parent of each ancestor
along the inheritance path, which probably increses the count some.
Your code doesn't quite work. The instances you gave only allow you to
inherit from the rightmost parent. GHC's inference algorithm seems to pick
one rule for a goal and try just that. To find instances in the first
parent and in other parents it needs to try both. I think I'll just give
up on inheriting methods, and generate unrelated instances for each class
that needs one.
Brandon
From veger at cistron.nl Sun Sep 28 00:45:22 2003
From: veger at cistron.nl (Peter J. Veger)
Date: Sat Sep 27 17:45:25 2003
Subject: (Off-topic) Question about categories
Message-ID: <001c01c38540$a7551cc0$0a02a8c0@veger3>
> I'm not sure if anyone mentioned the examples of a poset and a monoid as
categories.
> There is no "internal" structure in these. In the former, the objects are
the
> elements and there is a morphism between a and b iff a <= b. A functor
then becomes
> an order preserving map. In the latter, there is one object and the
morphisms are
> the elements. The identity is the identity map and if x and y are two
elements /
> morphisms then composition is xy. A functor is then a homomorphism.
> Dominic.
It is probably better to use the example of a preordered set.
A Preordered set is a set with a relation <=, that is
reflexive (x<=x) and transtive (x<=y & y<=z --> x<=z)
(but not necessarily antisymmetric, x<=y & y<=x --> x=y
as for a poset).
If, in a preordered set,
a is the unique morphism: x -> y and
b the unique morphism: y -> x, then
(writing x for the identity morphism id(x))
a.b=y and b.a=x
Categorically, x and y are isomorphic.
Concluding that x=y is not in the categorical language.
Of course, you should distinguish the category of preorders (posets,
monoids) from preorder (poset, monoid) as a category.
As for literature, you have the classic:
Saunders Mac Lane: Categories for the Working mathematician
but the working computer scientist may prefer:
Andrea Asperti and Guiseppe Longo: Categories, Types, and Structures (MIT
Press, 1991)
Michael Barr and Charles Wells: Category Theory for Computing Science (3rd
ed., Les Publication CRM, 1999)
idem, Introduction to Category Theory
(www.let.uu.nl/esslli/Courses/barr-wells.html)
Peter J. Veger, Best, Netherlands
From mai99dnn at userv1.informatik.uni-leipzig.de Mon Sep 29 03:55:18 2003
From: mai99dnn at userv1.informatik.uni-leipzig.de (Patrick Scheibe)
Date: Sun Sep 28 20:55:22 2003
Subject: haddock depencies to std-modules
Message-ID: <200309290255.18215.mai99dnn@userv1.informatik.uni-leipzig.de>
hello
I use haddock to create documentation. Everything is fine except of the
references to standard modules. If I am using standardtypes like Int or
String haddock wants to create crossrefs to these modules and fails because
of missing "sourcecode".
Is there a simple way to fix this? I've heard of interface files to create
right refs to existing docs, but that doesnt work. Whats the right way?
Cheers
Patrick
From simonmar at microsoft.com Mon Sep 29 13:37:55 2003
From: simonmar at microsoft.com (Simon Marlow)
Date: Mon Sep 29 07:43:24 2003
Subject: haddock depencies to std-modules
Message-ID: <3429668D0E777A499EE74A7952C382D1E5A385@EUR-MSG-01.europe.corp.microsoft.com>
> I use haddock to create documentation. Everything is fine
> except of the
> references to standard modules. If I am using standardtypes
> like Int or
> String haddock wants to create crossrefs to these modules and
> fails because
> of missing "sourcecode".
>
> Is there a simple way to fix this? I've heard of interface
> files to create
> right refs to existing docs, but that doesnt work. Whats the
> right way?
One way is to use the Haddock interface files that are distributed with
GHC. I haven't put any effort into making the process easy yet -
ideally Haddock should consult GHC's package database to find the
interface files, but it doesn't currently do this.
You'll find Haddock interface files in the same location as the
documentation when you install GHC (eg.
/usr/share/ghc-/html/base/base.haddock on a Linux system).
Cheers,
Simon
From shlomif at vipe.technion.ac.il Mon Sep 29 16:20:11 2003
From: shlomif at vipe.technion.ac.il (Shlomi Fish)
Date: Mon Sep 29 08:20:29 2003
Subject: RFC: "Haskell for Perl Programmers" Presentation
Message-ID:
At our local Perl Mongers club we have decided to hold a series of
introductions to foreign language. Being a big fan of Haskell (except for
any practical use), I wrote a "Haskell for Perl Programmers" intro:
http://vipe.technion.ac.il/~shlomif/lecture/Perl/Haskell/slides/
It's more or less complete, but there may still be things to add or
remove. Note that until now I did not write too much about the typing
facilities of Haskell. I could, though.
Regards,
Shlomi Fish
----------------------------------------------------------------------
Shlomi Fish shlomif@vipe.technion.ac.il
Home Page: http://t2.technion.ac.il/~shlomif/
An apple a day will keep a doctor away. Two apples a day will keep two
doctors away.
Falk Fish
From timd at macquarie.com.au Mon Sep 29 23:43:17 2003
From: timd at macquarie.com.au (Tim Docker)
Date: Mon Sep 29 08:43:30 2003
Subject: Database interface - would like advice on oracle library bind
ing
Message-ID: <675EC99F3F6BBF40BB989DC2E33E875D33F18C@nt_lon_exm01.macbank>
Alistair Bayley wrote:
> Still making slow progress on an Oracle database binding...
> now I'm trying to fit the API I have into some sort of
> abstract interface (like the one(s) discussed previously:
Since the previous dicussion I've discovered Krasimir
Angelov's HSQL interface as part of his HTOOLKIT:
https://sourceforge.net/project/showfiles.php?group_id=65248
This has a uniform abstract interface similar to the one
discussed, apparently implemented for MYSQL, ODBC, and
PostgreSQL. I've only played with the MYSQL variant.
If possible, it would seem sensible to provide a consistent
interface for your Oracle binding. If not, it may be worth
persuading him to generalise the interface.
Then again, perhaps you knew about this already.
Tim
From Alistair_Bayley at ldn.invesco.com Mon Sep 29 15:18:20 2003
From: Alistair_Bayley at ldn.invesco.com (Bayley, Alistair)
Date: Mon Sep 29 09:18:59 2003
Subject: Database interface - would like advice on oracle library bind
ing
Message-ID: <7DFF3BC6CA957441AEADA7F340BFAA3401B33763@GBLONEX11.lon.invesco.com>
Yes, I know of it.
Krasimir's code uses similar functions and types in the three bindings
(MySQL, ODBC, PostgreSql), but the bindings do not share a common interface
(AFAICT). Because they are so similar, making them support a common
interface shouldn't be a lot of work.
I was hoping the earlier discussions on database interfaces would converge
to a solution most interested parties agreed on. I'm still sold on the
left-fold interface discussed previously. Oleg claims it is sufficient, as
it can be automatically converted to a stream-like interface. I bit of me
agrees with you that I should be consistent with previous work, and another
bit says make it simple and elegant, and this leads me towards Oleg's
proposals (left-fold + auto-generated value extraction functions +
auto-generated stream functions).
Do others on this list (and elsewhere) have any further opinions as to how a
database interface ought to look?
> -----Original Message-----
> From: Tim Docker [mailto:timd@macquarie.com.au]
> Sent: 29 September 2003 13:43
> To: Bayley, Alistair; haskell-cafe@haskell.org
> Subject: RE: Database interface - would like advice on oracle library
> bind ing
>
>
>
> Alistair Bayley wrote:
>
> > Still making slow progress on an Oracle database binding...
> > now I'm trying to fit the API I have into some sort of
> > abstract interface (like the one(s) discussed previously:
>
>
> Since the previous dicussion I've discovered Krasimir
> Angelov's HSQL interface as part of his HTOOLKIT:
>
> https://sourceforge.net/project/showfiles.php?group_id=65248
>
> This has a uniform abstract interface similar to the one
> discussed, apparently implemented for MYSQL, ODBC, and
> PostgreSQL. I've only played with the MYSQL variant.
>
> If possible, it would seem sensible to provide a consistent
> interface for your Oracle binding. If not, it may be worth
> persuading him to generalise the interface.
>
> Then again, perhaps you knew about this already.
>
> Tim
*****************************************************************
The information in this email and in any attachments is
confidential and intended solely for the attention and use
of the named addressee(s). This information may be
subject to legal professional or other privilege or may
otherwise be protected by work product immunity or other
legal rules. It must not be disclosed to any person without
our authority.
If you are not the intended recipient, or a person
responsible for delivering it to the intended recipient, you
are not authorised to and must not disclose, copy,
distribute, or retain this message or any part of it.
*****************************************************************
From droundy at abridgegame.org Tue Sep 30 08:26:14 2003
From: droundy at abridgegame.org (David Roundy)
Date: Tue Sep 30 07:26:17 2003
Subject: swap leak problem
Message-ID: <20030930112611.GA30484@jdj5.mit.edu>
Hello. I've got a memory problem that is stumping me, and could use advice
in trying to fix it.
In brief, the heap of my application keeps increasing with time, until
after a few hours it uses up all my swap and gets killed. There is no
indication of a true memory leak. Heap profiling indicates that the
haskell memory usage (including stacks, via -xt) remains below its initial
peak value. Similarly, I've attached a sort of debugging counting
finalizer to my foreignPtrs (a static int in C land), and it's clear that
all the foreignPtrs I allocate are getting freed. Most of them are
allocated with mallocForeignPtrBytes anyways, which should be about as safe
an allocation method as one could use.
The allocation pattern of my code is as follows. It reads a gzipped patch
file into memory, parses it, then reads in a bunch of other files, and
writes modified versions of them. Then it reads in the next patch and
repeats. So it does large amounts of allocation and deallocation on a
periodic basis.
About half of the memory used is stored in foreignPtrs. With the exception
of the patch files (which I'll get to later), all foreignPtrs are generated
by mallocForeignPtrBytes or mallocForeignPtrArray.
The patch files are gzip compressed, so I don't know their size until I've
read them. I read the patch file one chunk at a time, and use reallocBytes
to allocate a bit more memory each time. I don't expect in general to be
calling reallocBytes more than four times per patch file. Of course, once
I'm done I convert to a foreignPtr via newForeignPtr finalizerFree.
My only idea as to the source of the problem is that it could be either a
result of memory fragmentation or of not cleaning up before allocating.
Neither theory is particularly convincing. Unfortunately, I'm at a loss as
to how to track this problem down, so any advise would be appreciated.
--
David Roundy
http://www.abridgegame.org/darcs
From droundy at abridgegame.org Tue Sep 30 08:31:03 2003
From: droundy at abridgegame.org (David Roundy)
Date: Tue Sep 30 07:31:12 2003
Subject: swap leak problem
In-Reply-To: <20030930112611.GA30484@jdj5.mit.edu>
References: <20030930112611.GA30484@jdj5.mit.edu>
Message-ID: <20030930113102.GB30484@jdj5.mit.edu>
Oh yes, one more datum. If I run hs_perform_gc before each and every
mallocForeignPtrBytes and reallocBytes, the leak goes much more slowly, and
the code gets much further in the job before getting killed. But it still
leaks, and still gets killed.
--
David Roundy
http://www.abridgegame.org