Re: [Haskell-cafe] Line noise

2008-09-22 Thread Andrew Coppin

Dan Piponi wrote:

I suspect that most of the complaints about line noise stem
from this - to beginners Haskell expressions just look like sequences
of identifiers with no apparent grammar to bind them together.
  


This was the exact complaint that some people voiced, yes. (The (.) and 
($) operators just compound the problem.)


Somebody else then came to my rescue and pointed out that everybody 
says Lisp is unreadable because it has too many brackets - despite the 
fact that those brackets theoretically make parsing utterly trivial. ;-)


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Line noise

2008-09-22 Thread Andrew Coppin

Mads Lindstrøm wrote:

Andrew Coppin wrote:

  
Idiomatic Haskell seems to consist *only* of single-letter variable 
names.



The more abstract (generic) thing gets, the less likely you will be able
to find a telling name. And if you cannot find a telling name, you can
just as well make it short. And as Haskell is more abstract, we get more
short identifiers. E.g. in your earlier sorting function:

  qsort (x:xs) = ...

what would you propose to call the elements?


Well, qsort (element : list) would be maximally intuitive, but who's 
going to implement it like that? ;-)


Now of course in C, you'd be forced to write something like

 list qsort(int x, list xs)

which makes it completely unambiguous what these things are - what their 
type is. But in Haskell, even if you add a type signature:


 qsort:: (Ord x) = [x] - [x]

Nobody is going to realise that [x] means a list. And it's still not 
clear where : comes from, or... well you can see why people are 
getting lost! ;-)



However, I will grant you that Map k v, could have used longer type
variables. But we are not alone with using one letter type variable
names http://java.sun.com/javase/6/docs/api/java/util/HashMap.html . And
frankly, in this specific case, I think most programmers (Haskell or
non-Haskell) will be able to guess what k and v means, when they are
standing right after Map.
  


Only if you can figure out that Map means what every other programming 
language on the face of the Earth calls a dictionary. (This took me a 
while!)


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Climbing up the shootout...

2008-09-22 Thread Andrew Coppin

Don Stewart wrote:

Thanks to those guys who've submitted parallel programs to the language
benchmarks game, we're climbing up the rankings, now in 3rd, and ahead
of C :)

http://shootout.alioth.debian.org/u64q/benchmark.php?test=alllang=all
  


Yay! This makes me very happy. ;-)

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] ANNOUNCE: citeproc-hs, a Haskell implementation of the Citation Style Language designed for Pandoc

2008-09-22 Thread Andrea Rossato
Hi Gwern,

On Fri, Sep 19, 2008 at 09:01:46PM -0400, Gwern Branwen wrote:
 Hi Andrea. So I was looking at the README. Does citeproc-hs only
 support adding refs from a .xml file when one's written in Pandoc
 markdown? That is, I don't see how I could take a .lhs file and a .bib
 file and produce one of the Pandoc-supported outputs. In particular,
 I'd really like to be able to go .lhs - .wiki, with refs; this would
 let me convert The Monad Reader articles for haskell.org.

as far as I remember Pandoc can deal with literate Haskell. Check here:
http://groups.google.com/group/pandoc-discuss/t/aaaf768ab730192

for bibtex databases, you can use Bibutils (check the citeproc-hs
homepage for a link): bibutils is a set of utilities for converting
from/to MODS to/from many different bibliographic databases.

As you know, Pandoc has a mediawiki writer, so, you should be able to
use extended markdown with referecnes to produce articles for the
wiki.

Keep in mind that pandoc latex reader doesn't use citeproc-hs (yet,
I'd like to add).

Andrea
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Line noise

2008-09-22 Thread Stephan Friedrichs
Andrew Coppin wrote:
 [...]
 - Variable names such as x and f aren't fabulously helpful to lost
 programmers trying to find their way.

I'm not a fan of cryptic variable names, either, and I try to use
descriptive names wherever I can. But in Haskell...

 - ... you often have variables, which have a scope of far less than a
   line such as in map (\(x, (_, y)) - (x, y) ... (cleaning
   intermediate results from a list).

 - ... things often get very abstract, so that it just feels wrong
   matching on, say, (socket:sockets) instead of (x:xs).

 
 [...]
 

//Stephan

-- 

Früher hieß es ja: Ich denke, also bin ich.
Heute weiß man: Es geht auch so.

 - Dieter Nuhr
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


RE: [Haskell-cafe] readFile and closing a file

2008-09-22 Thread Henning Thielemann


On Wed, 17 Sep 2008, Mitchell, Neil wrote:


I tend to use openFile, hGetContents, hClose - your initial readFile
like call should be openFile/hGetContents, which gives you a lazy
stream, and on a parse error call hClose.


I could use a function like
  withReadFile :: FilePath - (Handle - IO a) - IO a
  withReadFile name action = bracket openFile hClose ...

Then, if 'action' fails, the file can be properly closed. However, there 
is still a problem: Say, 'action' is a parser which produces a data 
structure lazily. Then further processing of that data structure of type 
'a' may again stop before completing the whole structure, which would also 
leave the file open. We have to force users to do all processing within 
'action' and to only return strict values. But how to do this?

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: [m..n] question

2008-09-22 Thread Jon Fairbairn
Richard A. O'Keefe [EMAIL PROTECTED] writes:

 Erlang's equivalent of [m..n] is lists:seq(M, N),
 which is currently defined to raise an exception when N  M.
 In particular, lists:seq(1, N) returns a list of length N
 when N  0, but not when N = 0.
 I'm currently arguing that lists:seq(1, 0) should be [],
 not an exception.  Oddly enough, I'm being beaten over the
 head with Haskell, of all things.

 In Haskell,
 The sequence enumFromTo e1 e3 is the list [e1,e1+1,e1+2,...e3].
  The list is empty if e1  e3.

 It is being claimed that the reason for this is that exceptions
 are problematic in Hasell, so the Haskell designers went out of
 their way to make this function total whether it made sense or not.

I'm pretty sure that's not true.  I'd like to be able to say
I know, I was there, but although I was there it was so
long ago that my memory isn't clear.  But it's clearly the
case that [5 .. 6] is [5, 6] (length 2) and [5 .. 5] has to
be [5] (length 1), so it's not unreasonable to expect that
[5, 4] be [] (length 0) -- having the induction extend down
to there makes most sense.  I'm fairly certain it was
arguments about induction and what constituted sensible
behaviour rather than our admitted dislike for exceptions
that carried the argument.



-- 
Jón Fairbairn [EMAIL PROTECTED]


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Climbing up the shootout...

2008-09-22 Thread Manlio Perillo

Don Stewart ha scritto:

Thanks to those guys who've submitted parallel programs to the language
benchmarks game, we're climbing up the rankings, now in 3rd, and ahead
of C :)



This is cheating, IMHO.
Some test comparisons are unfair.

The first problem is with the thread-ring benchmark.
Haskell uses the concurrent Haskell extension, but all other programs 
(with some exceptions) uses OS threads.
This is unfair, as an example a C program can make use of the GNU 
threads library, for user space threads), but there is no such program.


If I remove the thread-ring bench, then Haskell goes sixth, after Java 
and OCaml.



With parallel programs it is the same: other languages does not have a 
parallel version.


 [...]


Manlio Perillo
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Climbing up the shootout...

2008-09-22 Thread Thomas Davie


On 22 Sep 2008, at 11:46, Manlio Perillo wrote:


Don Stewart ha scritto:
Thanks to those guys who've submitted parallel programs to the  
language
benchmarks game, we're climbing up the rankings, now in 3rd, and  
ahead

of C :)


This is cheating, IMHO.
Some test comparisons are unfair.

The first problem is with the thread-ring benchmark.
Haskell uses the concurrent Haskell extension, but all other  
programs (with some exceptions) uses OS threads.
This is unfair, as an example a C program can make use of the GNU  
threads library, for user space threads), but there is no such  
program.


Who said that C *had* to use OS threads?  The point of the shootout is  
to show the relative strengths of the various languages, one of the  
strengths of Haskell is some excellent lightweight thread support,  
this is not present in C, so C does badly on the tests that check how  
well you can deal with small threads.


With parallel programs it is the same: other languages does not have  
a parallel version.


Yes, and the new benchmarks are *specifically* designed to test how  
fast programs are on more recent multi-core hardware, so again, the  
other languages are welcome to submit parallel versions... It just  
turns out that Haskell is pretty damn good at doing parallelism.


Bob
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Line noise

2008-09-22 Thread Ketil Malde
Andrew Coppin [EMAIL PROTECTED] writes:

 Idiomatic Haskell seems to consist *only* of single-letter variable
 names.

Good thing, too.

 Well, qsort (element : list) would be maximally intuitive, but who's
 going to implement it like that? ;-)

Why not listElement : restOfList ?

The rationale for having long names is that you have too many names,
and too large a scope to keep track of them all in your head.  Needing
long names is a symptom that your code is too complex, and that you
should refactor it.

The other problem with descriptive names is that it is not
automatically checked by the compiler, and thus it often ends up being
misleading.  Incorrect documentation is worse than no documentation.

  qsort:: (Ord x) = [x] - [x]

 Nobody is going to realise that [x] means a list.

And C is utterly incomprehensible, since from my Pascal background, I
just *know* that curly braces denote comments.  Come on, expecting
somebody to understand a language without an extremely basic
understanding of fundamental syntactical constructs is futile.

 well you can see why people are getting lost! ;-)

Yes, by refusing to adapt to any syntax but the single one they know.

 Only if you can figure out that Map means what every other
 programming language on the face of the Earth calls a
 dictionary. (This took me a while!)

Except for where it is called an associative array or hash table?
Terminology is inconsistent, Haskell happens to draw more of it from
math than from other programming languages.

-k
-- 
If I haven't seen further, it is by standing in the footprints of giants
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: ANNOUNCE: protocol-buffers-0.2.9 for Haskell is ready

2008-09-22 Thread Chris Kuklewicz

I am cross-posting this message to several lists.

I had learned the trick before the documentation was updated.  It seems I have 
used a very unreliable trick.  And the use castToSTUArray suggested 
alternative is a really poor one since I am not using arrays at all.


Who can suggest a way to cast from Float to Word32 and Double to Word64 using 
ghc?  The actual task is that I need to write out the Float as a little endian 
sequence of four bytes and also be able to read it back in.  The writing and 
reading are done in Put and Get monads to ByteString (from the binary package).


The alloca/poke/peek work around I have looks like
castWord32ToFloat :: Word32 - Float
castWord32ToFloat x = unsafePerformIO $
  alloca $ \p - poke p x  peek (castPtr p)

castFloatToWord32 :: Float - Word32
castFloatToWord32 x = unsafePerformIO $
  alloca $ \p - poke p x  peek (castPtr p)

The unsafeCoerce trick that is no longer working looks like:
castWord64ToDouble :: Word64 - Double
castWord64ToDouble (W64# w) = D# (unsafeCoerce# w)

castDoubleToWord64 :: Double - Word64
castDoubleToWord64 (D# d) = W64# (unsafeCoerce# d)

Any ideas? Or is the alloca trick the only way to do this?

  Chris


Ian Lynagh wrote:

Hi Chris,

On Sun, Sep 21, 2008 at 05:37:33PM +0100, Chris Kuklewicz wrote:

Also, I tried two tricks:
(D# x) - (W64# x) which works fine
(F# x) - (W32# x) which produced garbage, so I had to replace it with 
alloca/poke/peek.


This isn't supported, and I suspect is the cause of the -fasm problems.

Please see
http://hackage.haskell.org/trac/ghc/ticket/2209
for more details and suggested alternative.


Thanks
Ian



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] RE: readFile and closing a file

2008-09-22 Thread John Lato
 On Wed, 17 Sep 2008, Mitchell, Neil wrote:

 I tend to use openFile, hGetContents, hClose - your initial readFile
 like call should be openFile/hGetContents, which gives you a lazy
 stream, and on a parse error call hClose.

 I could use a function like
   withReadFile :: FilePath - (Handle - IO a) - IO a
   withReadFile name action = bracket openFile hClose ...

 Then, if 'action' fails, the file can be properly closed. However, there
 is still a problem: Say, 'action' is a parser which produces a data
 structure lazily. Then further processing of that data structure of type
 'a' may again stop before completing the whole structure, which would also
 leave the file open. We have to force users to do all processing within
 'action' and to only return strict values. But how to do this?

I used rnf from Control.Parallel.Strategies when dealing with a
similar problem.  Would it work in your case?

To merge discussion from a related thread:

IMO, the question is how much should a language/library prevent the
user from shooting himself in the foot?  The biggest problem with lazy
IO, IMO, is that it presents several opportunities to do so.  The
three biggest causes I've dealt with are handle leaks, insufficiently
evaluated data structures, and problems with garbage collection as in
the naive 'mean xs = sum xs / length xs' implementation.

There are some idioms that can help with the first two cases, namely
the 'with*' paradigm and 'rnf', but the third problem requires that
the programmer know how stuff works to avoid poor implementations.
While that's not bad per se, in some cases I think it's far too easy
for the unwitting, or even the slightly distracted, to get caught in
traps.

I'm facing a design decision ATM related to this.  I can use something
like lazy bytestrings, in which the chunkiness and laziness is reified
into the datastructure, or an Iterator-style fold for consuming data.
The advantage of the former approach is that it's well understood by
most users and has proven good performance, while on the downside I
could see it easily leading to memory exhaustion.  I think the problem
with lazy bytestrings, in particular, is that the foldChunks is so
well hidden from most consumers that it's easy to hold references that
prevent consumed chunks from being reclaimed by the GC.  When dealing
with data in the hundreds of MBs, or GB range, this is a problem.

An Enumerator, on the other hand, makes the fold explicit, so users
are required to think about the best way to consume data.  It's much
harder to unintentionally hold references.  This is quite appealing.
Based on my own tests so far performance is certainly competitive.
Assuming a good implementation, handle leaks can also be prevented.
On the downside, it's a very poor model if random access is required,
and users aren't as familiar with it, in addition to some of the
questions Don raises.

Back onto the topic at hand - 'action' could be a parser passed into
an enumerator.  Since it would read strictly, the action could end the
read when it has enough data.  That's another approach that I think
would work with your problem.

Well, that's my 2cents.

John Lato
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: ANNOUNCE: protocol-buffers-0.2.9 for Haskell is ready

2008-09-22 Thread Yitzchak Gale
Chris Kuklewicz wrote:
 Who can suggest a way to cast from Float to Word32 and Double to Word64
 using ghc?  The actual task is that I need to write out the Float as a
 little endian sequence of four bytes and also be able to read it back in.
  The writing and reading are done in Put and Get monads to ByteString (from
 the binary package).

I think alloca-like hacks is really the wrong direction and asking
for trouble.

You are trying to translate between platform-dependent native floats,
and IEEE floats in a specified platform-independent binary format
for Google. So use encodeFloat/decodeFloat - fast primitives in
GHC - on the native side, and a hand-written Binary instance for
the exact format you need on the Google side.

My opinion, YMMV.

Regards,
Yitz
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Climbing up the shootout...

2008-09-22 Thread ChrisK
And, though I had never seen it before, the current winner for speed is ATS ( 
http://www.ats-lang.org/ ) which is dependently-typed functional language.



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re[2]: [Haskell-cafe] Climbing up the shootout...

2008-09-22 Thread Bulat Ziganshin
Hello Manlio,

Monday, September 22, 2008, 1:46:55 PM, you wrote:

 This is cheating, IMHO.
 Some test comparisons are unfair.

this overall test is uselles for speed comparison. afair, there are
only 2-3 programs whose speed isn't heavily depend on libraries. in
DNA test, for example, Tcl (or PHP?) was leader just because it has
better regexp library

to make things even funnier, this test allows to use libs bundled to
compiler, but not 3rd-arty ones. so ghc (not Haskell!) what includes
more built-in libs than gcc looks like a leader. of course, noone uses
bare ghc or gcc in real world

even benchamrks that test pure speed of compiled code are useless
because

1) they are imited by RAM speed, not speed of code itself
2) there uis a fashion in Haskell world to write for shootout in the
very low-level style, which isn't actually used in real programming
and actually understood only by a few wizards developing
high-performance haskell code

so actually that this shootout shows is that
1) in real world, program speed more depends on libs that on
compilers. if you go to compare weak language plus lot of libs with a
strong language with a few libs first variant will win (unless you go
to reimplement all these libs at your own)

2) highly-optimized Haskell code is only 2-3 times slower than real C
code produces by average C programmer. taken into account that such
Haskell code is written many times slower than C one and need much
more knowledge, Haskell hardly can be compared to C

3) if you need to compare real-world Haskell code with C one, you may
look at these papers:

An approach to fast arrays in Haskell
http://www.cse.unsw.edu.au/~chak/papers/afp-arrays.ps.gz

Rewriting Haskell Strings
http://www.cse.unsw.edu.au/~dons/papers/fusion.pdf

that they call naive approach is real Haskell programs not speeded
up by special libs


-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: ANNOUNCE: protocol-buffers-0.2.9 for Haskell is ready

2008-09-22 Thread Bulat Ziganshin
Hello Chris,

Monday, September 22, 2008, 2:48:16 PM, you wrote:

 used a very unreliable trick.  And the use castToSTUArray suggested
 alternative is a really poor one since I am not using arrays at all.

castToSTUArray does the same as your code, only in ST monad so you can
skip unsafePerformIO trick

if you dn't know, ST is a subset of IO monad with a limited set of
operations guaranteed to not have side-effects. so,

cvt x = unsafePerformIO $
do alloca $ \place - do
   poke place x
   peek place

and

cvt x = runST $
do place - newArray (0,1)
   writeArray place 0 x
   readArray place 0

generates almost the same code (the only difference is kind of memory
allocated)

-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Line noise

2008-09-22 Thread Daniel Fischer
Am Montag, 22. September 2008 08:32 schrieb Andrew Coppin:
  However, I will grant you that Map k v, could have used longer type
  variables. But we are not alone with using one letter type variable
  names http://java.sun.com/javase/6/docs/api/java/util/HashMap.html . And
  frankly, in this specific case, I think most programmers (Haskell or
  non-Haskell) will be able to guess what k and v means, when they are
  standing right after Map.

 Only if you can figure out that Map means what every other programming
 language on the face of the Earth calls a dictionary. (This took me a
 while!)

So, when did Java leave the face of the earth?
Seriously, I find Map a far clearer term than dictionary and would've had 
problems grokking the latter. I guess you've just been exposed to the wrong 
languages for too long.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Munging wiki articles with tagsoup

2008-09-22 Thread Neil Mitchell
Hi

 For no escaping of any characters, or more likely do something like ,
  and  conversions. See the docs:
 http://hackage.haskell.org/packages/archive/tagsoup/0.6/doc/html/Text-HTML-TagSoup-Render.html

 Well, I did look at that Haddock page, as well as the others. But honestly, 
 just a bare line like 'renderTagsOptions :: RenderOptions - [Tag] - String' 
 doesn't help me - it doesn't tell me that 'that's default behavior, but you 
 can override it thusly'.

The lack of sufficient documentation is a bug. I've filed it at:

http://code.google.com/p/ndmitchell/issues/detail?id=91

If someone wants to write the documentation and submit a patch, that
would be great. Otherwise, I'll fix it at some unknown point in the
future.

Thanks

Neil
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Line noise

2008-09-22 Thread david48
On Sun, Sep 21, 2008 at 10:04 PM, Claus Reinke [EMAIL PROTECTED] wrote:
 Once your readers understand
 your code, you can add the one-liner and ask for applause

This should make it HWN's quotes of the week !
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Ropes

2008-09-22 Thread Rafael Gustavo da Cunha Pereira Pinto
That is a good idea!

If I implement head, tail, take drop operations, I can use my KMP
implementation out of the box...



On Sun, Sep 21, 2008 at 11:10, Nicolas Pouillard 
[EMAIL PROTECTED] wrote:

 Excerpts from Rafael Gustavo da Cunha Pereira Pinto's message of Sat Sep 20
 12:54:26 +0200 2008:
  I am doing the ICFPC07 task right now, to learn Haskell and tried to use
 the
  Sequence, but the final code is too damn slow (a few iterations per
  minute!).

 Is your structure a sequence of *Char*s, if so you should consider to use a
 sequence of strict bytestrings of a given size (chunks).

  The DNA needs only 2 operations: head (or take) and concat.
 
  I am thinking in using ropes for the DNA and sequences for all the rest
  (patterns, templates and RNA).
 
  On Fri, Sep 19, 2008 at 23:15, Ryan Ingram [EMAIL PROTECTED] wrote:
 
   I think Data.Sequence uses fingertrees which are pretty fast.
  
   I used a handgrown rope-like structure for ICFPC07 but I wish I had
   known about Sequence; it would have likely just been better.
  
-- ryan
  
   2008/9/19 Rafael Gustavo da Cunha Pereira Pinto 
   [EMAIL PROTECTED]:
Hi all,
   
Is there any implementation of the rope data structure in Haskell?
   
I couldn't find any on Hackage, and I am intending to implement it.
   
Regards,
   
Rafael Gustavo da Cunha Pereira Pinto
Electronic Engineer, MSc.
   
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
   
   
  
 

 --
 Nicolas Pouillard aka Ertai




-- 
Rafael Gustavo da Cunha Pereira Pinto
Electronic Engineer, MSc.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] RE: readFile and closing a file

2008-09-22 Thread Don Stewart
jwlato:
  On Wed, 17 Sep 2008, Mitchell, Neil wrote:
 
  I tend to use openFile, hGetContents, hClose - your initial readFile
  like call should be openFile/hGetContents, which gives you a lazy
  stream, and on a parse error call hClose.
 
  I could use a function like
withReadFile :: FilePath - (Handle - IO a) - IO a
withReadFile name action = bracket openFile hClose ...
 
  Then, if 'action' fails, the file can be properly closed. However, there
  is still a problem: Say, 'action' is a parser which produces a data
  structure lazily. Then further processing of that data structure of type
  'a' may again stop before completing the whole structure, which would also
  leave the file open. We have to force users to do all processing within
  'action' and to only return strict values. But how to do this?
 
 I used rnf from Control.Parallel.Strategies when dealing with a
 similar problem.  Would it work in your case?
 
 To merge discussion from a related thread:
 
 IMO, the question is how much should a language/library prevent the
 user from shooting himself in the foot?  The biggest problem with lazy
 IO, IMO, is that it presents several opportunities to do so.  The
 three biggest causes I've dealt with are handle leaks, insufficiently
 evaluated data structures, and problems with garbage collection as in
 the naive 'mean xs = sum xs / length xs' implementation.
 
 There are some idioms that can help with the first two cases, namely
 the 'with*' paradigm and 'rnf', but the third problem requires that
 the programmer know how stuff works to avoid poor implementations.
 While that's not bad per se, in some cases I think it's far too easy
 for the unwitting, or even the slightly distracted, to get caught in
 traps.
 
 I'm facing a design decision ATM related to this.  I can use something
 like lazy bytestrings, in which the chunkiness and laziness is reified
 into the datastructure, or an Iterator-style fold for consuming data.
 The advantage of the former approach is that it's well understood by
 most users and has proven good performance, while on the downside I
 could see it easily leading to memory exhaustion.  I think the problem
 with lazy bytestrings, in particular, is that the foldChunks is so
 well hidden from most consumers that it's easy to hold references that
 prevent consumed chunks from being reclaimed by the GC.  When dealing
 with data in the hundreds of MBs, or GB range, this is a problem.
 
 An Enumerator, on the other hand, makes the fold explicit, so users
 are required to think about the best way to consume data.  It's much
 harder to unintentionally hold references.  This is quite appealing.
 Based on my own tests so far performance is certainly competitive.
 Assuming a good implementation, handle leaks can also be prevented.
 On the downside, it's a very poor model if random access is required,
 and users aren't as familiar with it, in addition to some of the
 questions Don raises.

Yes, I'm certain we can reach the performance of, or outperform, lazy
(cache-sized chunk) bytestrings using enumerators on chunks, but the
model is somewhat unfamiliar. Structuring the api such that people can
write programs in this style will be the challenge.

-- Don
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Updated formlets sample?

2008-09-22 Thread Martin Huschenbett

Hi Chris,

you're absolutely right. The mistake was in the where-part of withForm. 
The function handleOk' gets an environment d as argument but uses an 
extractor that was created without passing d to runFormState. I've put a 
corrected version on hpaste [1] and also posted it to the wiki on 
haskell.org [2]. Hope this is ok for you?


Regards,

Martin.

[1] http://hpaste.org/10568#a1
[2] http://haskell.org/haskellwiki/Formlets

Chris Eidhof schrieb:
That means that you don't have input0 in your environment, maybe you're 
passing in an empty environment?


-chris

On 21 sep 2008, at 12:11, Martin Huschenbett wrote:


Hi Chris,

thanks for the updated example. Compiling works now. But when I try to 
run it I alway get error messages like


[input0 is not in the data,input1 is not in the data]

Regards,

Martin.

Chris Eidhof schrieb:

Hey Martin,
On 19 sep 2008, at 04:14, Martin Huschenbett wrote:
I found a blog post concerning formlets [1] in the web. Since looks 
very interesting I tried to compile the sample code with recent 
versions of HAppS and formlets from hackage. But this didn't work as 
the API of formlets has changed since this post.


I tried to adopt the code to the new API but I was unable to finish 
this since there is a new monadic context I don't know to handle in 
the right way.


So my question is, is there an updated version of this sample code 
in the web or has anybody tried to adopt it and can send me the 
results?
Yes, I'm sorry for that. The API is still very immature and due to 
changes, that's also why it hasn't been officially announced yet. 
I've just put an updated example at http://hpaste.org/10568, hope 
that'll work for you. I guess we should build a small homepage / 
wikipage that always has an up-to-date example.

-chris

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Line noise

2008-09-22 Thread Sebastian Sylvan
On Mon, Sep 22, 2008 at 1:50 PM, Daniel Fischer [EMAIL PROTECTED]wrote:

 Am Montag, 22. September 2008 08:32 schrieb Andrew Coppin:
   However, I will grant you that Map k v, could have used longer type
   variables. But we are not alone with using one letter type variable
   names http://java.sun.com/javase/6/docs/api/java/util/HashMap.html .
 And
   frankly, in this specific case, I think most programmers (Haskell or
   non-Haskell) will be able to guess what k and v means, when they are
   standing right after Map.
 
  Only if you can figure out that Map means what every other programming
  language on the face of the Earth calls a dictionary. (This took me a
  while!)

 So, when did Java leave the face of the earth?


At the same time as C++ presumably. I hadn't really noticed, but I'll be the
first to say: Good riddance!


-- 
Sebastian Sylvan
+44(0)7857-300802
UIN: 44640862
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: Re[2]: [Haskell-cafe] Climbing up the shootout...

2008-09-22 Thread Simon Brenner
On Mon, Sep 22, 2008 at 2:07 PM, Bulat Ziganshin
[EMAIL PROTECTED] wrote:
 this overall test is uselles for speed comparison. afair, there are
 only 2-3 programs whose speed isn't heavily depend on libraries. in
 DNA test, for example, Tcl (or PHP?) was leader just because it has
 better regexp library

On the regex-dna benchmark, I'll have to agree. It's unfortunate to
have a benchmark so dependent on the set of libraries included in the
distribution, and e.g. Text.Regex.PCRE kicks Text.Regex.Posix's behind
in this benchmark - but we probably can't use it only because one's
bundled and the other isn't. Maybe we could roll our own regexp engine
for this specific benchmark though (for example, Text.Regex.TDFA is
within 10% or something of PCRE and AFAIK pure Haskell - a customized
and downsized version of that could probably be made quite
competitive).

 to make things even funnier, this test allows to use libs bundled to
 compiler, but not 3rd-arty ones. so ghc (not Haskell!) what includes
 more built-in libs than gcc looks like a leader. of course, noone uses
 bare ghc or gcc in real world

I don't think it's ever claimed that the shootout is a fair benchmark
of real-world problems :D

 2) there uis a fashion in Haskell world to write for shootout in the
 very low-level style, which isn't actually used in real programming
 and actually understood only by a few wizards developing
 high-performance haskell code

That is certainly the case with a few of the benchmark
implementations, and in the past it was required to get the
performance. In some cases it's also due simply to the haskell
implementation being a straight-from-C port - which necessitates using
pointers and putting everything in IO etc... Some of that haskell code
is among the least readable code I've ever read (see e.g. the fannkuch
benchmark at 
http://shootout.alioth.debian.org/u64q/benchmark.php?test=fannkuchlang=ghc).
But that's what you get when porting pointer-rich C code directly into
Haskell :)

With bytestrings, unboxed arrays, light-weight threads and other
tricks, we can usually replace all those ugly low-level programs with
nice high-level haskell ones - it's all about allowing the compiler to
do good stuff with naive (or at least naive-looking) code, and
teaching it how to cut through the abstractions. (As well as using the
right abstractions, of course...)

// Simon
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re[4]: [Haskell-cafe] Climbing up the shootout...

2008-09-22 Thread Bulat Ziganshin
Hello Simon,

Monday, September 22, 2008, 9:03:52 PM, you wrote:

 With bytestrings, unboxed arrays, light-weight threads and other
 tricks, we can usually replace all those ugly low-level programs with
 nice high-level haskell ones

i don't think that these 3 libs allows to write high-level
high-performance code in *most* cases. just for example, try to write wc
without using words

-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] hGetContents and lazyness

2008-09-22 Thread Max Vasin
Hello, haskellers!

Suppose we have function (it filters package filenames from apt Packages file):

 getPackageList :: FilePath - IO [FilePath]
 getPackageList packageFile = withFile packageFile ReadMode $
  \h - do c - hGetContents h
   return $ map (drop 10) $ filter 
 (startsWith Filename:) $ lines c -- (1)
 where startsWith [] _ = True
   startsWith _ [] = False
   startsWith (x:xs) (y:ys) | x == y= startsWith xs ys
| otherwise = False

When, I apply it to a Packages file I (surely) get an empty list. This is an 
expected result due to
lazyness of hGetContents. I tried changing line (1) to

 return $ map (drop 10) $ filter (startsWith Filename:) $! lines c

or 

 return $ map (drop 10) $! filter (startsWith Filename:) $! lines c

with no success.

Chaning it to

 return $! map (drop 10) $ filter (startsWith Filename:) $ lines c

makes getPackageList function return several (but not all) filenames.

What I'm missing? And how can I fix my code?

--
WBR,
Max Vasin.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: Re[2]: [Haskell-cafe] Climbing up the shootout...

2008-09-22 Thread Isaac Gouy

--- Simon Brenner [EMAIL PROTECTED] wrote:

 On Mon, Sep 22, 2008 at 2:07 PM, Bulat Ziganshin
 [EMAIL PROTECTED] wrote:
  this overall test is uselles for speed comparison. afair, there are
  only 2-3 programs whose speed isn't heavily depend on libraries. in
  DNA test, for example, Tcl (or PHP?) was leader just because it has
  better regexp library
 
 On the regex-dna benchmark, I'll have to agree. It's unfortunate to
 have a benchmark so dependent on the set of libraries included in the
 distribution, and e.g. Text.Regex.PCRE kicks Text.Regex.Posix's
 behind
 in this benchmark - but we probably can't use it only because one's
 bundled and the other isn't. Maybe we could roll our own regexp
 engine
 for this specific benchmark though (for example, Text.Regex.TDFA is
 within 10% or something of PCRE and AFAIK pure Haskell - a customized
 and downsized version of that could probably be made quite
 competitive).

You could always suggest use of Text.Regex.PCRE, provide a program and
instructions on how to install Text.Regex.PCRE on Ubuntu.


-snip-
 With bytestrings, unboxed arrays, light-weight threads and other
 tricks, we can usually replace all those ugly low-level programs with
 nice high-level haskell ones ...

Go do!


  
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: Re[2]: [Haskell-cafe] Climbing up the shootout...

2008-09-22 Thread Don Stewart
igouy2:
 
 --- Simon Brenner [EMAIL PROTECTED] wrote:
 
  On Mon, Sep 22, 2008 at 2:07 PM, Bulat Ziganshin
  [EMAIL PROTECTED] wrote:
   this overall test is uselles for speed comparison. afair, there are
   only 2-3 programs whose speed isn't heavily depend on libraries. in
   DNA test, for example, Tcl (or PHP?) was leader just because it has
   better regexp library
  
  On the regex-dna benchmark, I'll have to agree. It's unfortunate to
  have a benchmark so dependent on the set of libraries included in the
  distribution, and e.g. Text.Regex.PCRE kicks Text.Regex.Posix's
  behind
  in this benchmark - but we probably can't use it only because one's
  bundled and the other isn't. Maybe we could roll our own regexp
  engine
  for this specific benchmark though (for example, Text.Regex.TDFA is
  within 10% or something of PCRE and AFAIK pure Haskell - a customized
  and downsized version of that could probably be made quite
  competitive).
 
 You could always suggest use of Text.Regex.PCRE, provide a program and
 instructions on how to install Text.Regex.PCRE on Ubuntu.
 
 -snip-
  With bytestrings, unboxed arrays, light-weight threads and other
  tricks, we can usually replace all those ugly low-level programs with
  nice high-level haskell ones ...
 
 Go do!
 

All is in hand. Tim Newsham's uploaded a regex-pcre and regex-posix
entry to the wiki, and I'm testing now on quad core. If it survives
testing, we'll submit it to Isaac.

-- Don
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Fwd: [Haskell-cafe] hGetContents and lazyness

2008-09-22 Thread Rafael Gustavo da Cunha Pereira Pinto
-- Forwarded message --
From: Rafael Gustavo da Cunha Pereira Pinto [EMAIL PROTECTED]
Date: Mon, Sep 22, 2008 at 15:46
Subject: Re: [Haskell-cafe] hGetContents and lazyness
To: Max Vasin [EMAIL PROTECTED]


Why don't you use OpenFile?

 getPackageList packageFile = do
  h - OpenFile packageFile ReadMode
  c - hGetContents h
  return $ map (drop 10) $ filter (startsWith
Filename:) $ lines c

I am not at home so I don't have GHC around here, but this usually works for
me!

Anyway, it also depends on who is consuming the IO [FilePath] data returned.
It will not be evaluated unless asked for!


On Mon, Sep 22, 2008 at 14:52, Max Vasin [EMAIL PROTECTED] wrote:

 Hello, haskellers!

 Suppose we have function (it filters package filenames from apt Packages
 file):

  getPackageList :: FilePath - IO [FilePath]
  getPackageList packageFile = withFile packageFile ReadMode $
   \h - do c - hGetContents h
return $ map (drop 10) $ filter
 (startsWith Filename:) $ lines c -- (1)
  where startsWith [] _ = True
startsWith _ [] = False
startsWith (x:xs) (y:ys) | x == y= startsWith xs ys
 | otherwise = False

 When, I apply it to a Packages file I (surely) get an empty list. This is
 an expected result due to
 lazyness of hGetContents. I tried changing line (1) to

  return $ map (drop 10) $ filter (startsWith Filename:) $! lines c

 or

  return $ map (drop 10) $! filter (startsWith Filename:) $! lines c

 with no success.

 Chaning it to

  return $! map (drop 10) $ filter (startsWith Filename:) $ lines c

 makes getPackageList function return several (but not all) filenames.

 What I'm missing? And how can I fix my code?

 --
 WBR,
 Max Vasin.

 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe




-- 
Rafael Gustavo da Cunha Pereira Pinto
Electronic Engineer, MSc.



-- 
Rafael Gustavo da Cunha Pereira Pinto
Electronic Engineer, MSc.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Line noise

2008-09-22 Thread Luke Palmer
On Sun, Sep 21, 2008 at 1:10 PM, Andrew Coppin
[EMAIL PROTECTED] wrote:
 I posted a snippet of code which included the phrase

  mapM_ (\(n,v) - putStrLn $ [ ++ show n ++ ] =  ++ show v) (zip [0..]
 vs)

 To somebody familiar with Haskell, that is as clear as day. But to a
 newbie... well *you* try explaining that you start at the left end, take the
 thing in brackets, process it from left to right, then take the other thing
 in brackets, process the right side of it, then pass that to putStrLn, oh,
 but that thing right at the left edge is the argument list, and then pass
 the whole lot to mapM_, which is... are you still with me??

 As one experienced C++ programmer put it, there is no clear flow from left
 to right or right to left.

This is actually one of the two main metrics I use when I'm writing
code -- I try to keep the information content in my code local, so you
don't have to scan across the screen to see what n corresponds to.
This is equivalent to maintaining a left-to-right or right-to-left
flow (and really which direction it is depends more on reading style
than writing style).

The other one I picked up from Perl of all places, and that is end
weight.  In English we tend to put the important parts (the essence)
of the sentence at the front, and leave the details for the end.  So I
like to emulate that in Haskell when I can.  There is little I loathe
more than the style:

   map (\x - ...
 ...
 ...
 ...
 ...) xs

As such, the probability that I would have written the mapM_ line
above is very low, since it violates both of these.  In this case,
switching to forM_ brings it much closer to my style:

  forM_  (zip [0..] vs) $ \(n,v) - putStrLn $ [ ++ show n ++ ] =  ++ show v

That is because the details of this sentence are in the function, so I
put it at the end.  Also the corresponding [0..] and n are close
together, as are the corresponding vs and v.

Luke
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: Re[4]: [Haskell-cafe] Climbing up the shootout...

2008-09-22 Thread Graham Fawcett
On Mon, Sep 22, 2008 at 1:12 PM, Bulat Ziganshin
[EMAIL PROTECTED] wrote:
 Hello Simon,

 Monday, September 22, 2008, 9:03:52 PM, you wrote:

 With bytestrings, unboxed arrays, light-weight threads and other
 tricks, we can usually replace all those ugly low-level programs with
 nice high-level haskell ones

 i don't think that these 3 libs allows to write high-level
 high-performance code in *most* cases. just for example, try to write wc
 without using words.

To a newbie, that's a cryptic statement. Are you saying that these
libs aren't needed to make a high-performance wc, and that the
Prelude functions are sufficient? (I note too that there is
Data.ByteString.Char8.words, but I assume you are talking about the
Prelude function.)

Graham
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re[6]: [Haskell-cafe] Climbing up the shootout...

2008-09-22 Thread Bulat Ziganshin
Hello Graham,

 i don't think that these 3 libs allows to write high-level
 high-performance code in *most* cases. just for example, try to write wc
 without using words.

 To a newbie, that's a cryptic statement. Are you saying that these
 libs aren't needed to make a high-performance wc, and that the
 Prelude functions are sufficient? (I note too that there is
 Data.ByteString.Char8.words, but I assume you are talking about the
 Prelude function.)

i mean that naive haskell code is very slow and 3 or 5 or twelve libs
can't solve the problem of ghc generating slow code


-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re[2]: [Haskell-cafe] Line noise

2008-09-22 Thread Bulat Ziganshin
Hello Luke,

Monday, September 22, 2008, 11:00:12 PM, you wrote:

  mapM_ (\(n,v) - putStrLn $ [ ++ show n ++ ] =  ++ show v) (zip [0..]
 vs)

   forM_  (zip [0..] vs) $ \(n,v) - putStrLn $ [ ++ show n ++ ] =  ++ 
 show v

for  (zip [0..] vs) $ \(n,v) - do
  putStrLn $ [ ++ show n ++ ] =  ++ show v
  ...

it's rather close to C/Pascal/... loops although it will be great to
have more sugar here



-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] hGetContents and lazyness

2008-09-22 Thread Micah Cowan
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Max Vasin wrote:
 Hello, haskellers!
 
 Suppose we have function (it filters package filenames from apt Packages 
 file):
 
 getPackageList :: FilePath - IO [FilePath]
 getPackageList packageFile = withFile packageFile ReadMode $
  \h - do c - hGetContents h
   return $ map (drop 10) $ filter 
 (startsWith Filename:) $ lines c -- (1)
 where startsWith [] _ = True
   startsWith _ [] = False
   startsWith (x:xs) (y:ys) | x == y= startsWith xs ys
| otherwise = False
 
 When, I apply it to a Packages file I (surely) get an empty list. This is an 
 expected result due to
 lazyness of hGetContents.

Combined with the fact that you're not evaluating its non-strict result
until after the file handle has been closed, yes.

Your current set of IO actions is probably similar to:
  . open file
  . process file
  . close file
  . use results from processing the file.
where the first three steps are all handled by your getPackageList. To
avoid either getting incomplete (or empty) results, or having to
strictify everything with $!, it'd be better for you to use a process
more like:
  . open file
  . process file
  . use results from processing the file.
  . close file
probably by moving the withFile outside of getPackageList, to wrap a
function that prints the results after they've been obtained. The
function passed to withFile should generally include all the processing
related to the file and its results, I believe.

 I tried changing line (1) to
 
 return $ map (drop 10) $ filter (startsWith Filename:) $! lines c

The $! forces strictness, but since it's deep in the result, it isn't
evaluated until it's too late.

 Chaning it to
 
 return $! map (drop 10) $ filter (startsWith Filename:) $ lines c
 
 makes getPackageList function return several (but not all) filenames.

I think we'd need to see the actual input and expected output, to
understand what's going wrong here. It worked fine for me, for small tests.

By the way, it's good policy to always post complete, runnable examples.
Requiring anyone who wants to help you to write additional code just to
get it to run decreases the chances that someone will bother to do so.

(Disclaimer: I'm quite new to Haskell myself, so take what I say with
more than a pinch of salt.)

- --
Micah J. Cowan
Programmer, musician, typesetting enthusiast, gamer.
GNU Maintainer: wget, screen, teseq
http://micah.cowan.name/
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.7 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFI1/AT7M8hyUobTrERAo5qAJ9PKLbQv09UGffmxy6/eRuGS1eYbQCgj3gH
8zvxMrGk5pvCMCOQ6LVz0Yo=
=GAvg
-END PGP SIGNATURE-
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] how do i use quickcheck in the IO monad?

2008-09-22 Thread Anatoly Yakovenko
If i have functions in the IO monad, is there a way to use quickcheck
to test them?  I have a bunch of C bindings that unfortunately are not
safe.  But i would like to be able to use QuickCheck to test them.

Thanks,
Anatoly
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: Re[2]: [Haskell-cafe] Climbing up the shootout...

2008-09-22 Thread Don Stewart
igouy2:
 
 --- Simon Brenner [EMAIL PROTECTED] wrote:
 
  On Mon, Sep 22, 2008 at 2:07 PM, Bulat Ziganshin
  [EMAIL PROTECTED] wrote:
   this overall test is uselles for speed comparison. afair, there are
   only 2-3 programs whose speed isn't heavily depend on libraries. in
   DNA test, for example, Tcl (or PHP?) was leader just because it has
   better regexp library
  
  On the regex-dna benchmark, I'll have to agree. It's unfortunate to
  have a benchmark so dependent on the set of libraries included in the
  distribution, and e.g. Text.Regex.PCRE kicks Text.Regex.Posix's
  behind
  in this benchmark - but we probably can't use it only because one's
  bundled and the other isn't. Maybe we could roll our own regexp
  engine
  for this specific benchmark though (for example, Text.Regex.TDFA is
  within 10% or something of PCRE and AFAIK pure Haskell - a customized
  and downsized version of that could probably be made quite
  competitive).
 
 You could always suggest use of Text.Regex.PCRE, provide a program and
 instructions on how to install Text.Regex.PCRE on Ubuntu.

I've now submitted a Text.Regex.PCRE parallelised entry written by Tim
Newsham. It is by far the fastest haskell regex entry so far (down to 9s
on quad core, from 100+ seconds on single core for the old entry),


http://alioth.debian.org/tracker/index.php?func=detailaid=311132group_id=30402atid=411646

It does require the regex-pcre library, which if it isn't in your
package system on Ubuntu, you can certainly build,

$ wget 
http://hackage.haskell.org/packages/archive/regex-pcre-builtin/0.94.2.0.7.7/regex-pcre-builtin-0.94.2.0.7.7.t
ar.gz
$ tar xzf regex-pcre-builtin-0.94.2.0.7.7.tar.gz
$ cd regex-pcre-builtin-0.94.2.0.7.7
$ runhaskell Setup.hs configure --prefix=$HOME
$ runhaskell Setup.hs build
$ sudo runhaskell Setup.hs install

I also included these details on the ticket.

It uses a simple parMap strategy.

Cheers,
  Don
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: Re[6]: [Haskell-cafe] Climbing up the shootout...

2008-09-22 Thread Isaac Gouy

--- Bulat Ziganshin [EMAIL PROTECTED] wrote:

 Hello Graham,
 
  i don't think that these 3 libs allows to write high-level
  high-performance code in *most* cases. just for example, try to
 write wc
  without using words.
 
  To a newbie, that's a cryptic statement. Are you saying that these
  libs aren't needed to make a high-performance wc, and that the
  Prelude functions are sufficient? (I note too that there is
  Data.ByteString.Char8.words, but I assume you are talking about the
  Prelude function.)
 
 i mean that naive haskell code is very slow and 3 or 5 or twelve libs
 can't solve the problem of ghc generating slow code

Is there something particularly fascinating about naive code written in
any language? 


  
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Climbing up the shootout...

2008-09-22 Thread Manlio Perillo

Don Stewart ha scritto:

[...]
I've now submitted a Text.Regex.PCRE parallelised entry written by Tim
Newsham. It is by far the fastest haskell regex entry so far (down to 9s
on quad core, from 100+ seconds on single core for the old entry),


http://alioth.debian.org/tracker/index.php?func=detailaid=311132group_id=30402atid=411646

It does require the regex-pcre library, which if it isn't in your
package system on Ubuntu, you can certainly build,



What performance gain do you obtain using regex-pcre-builtin against a 
native Haskell regex library?


 [...]


Thanks  Manlio Perillo
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re[8]: [Haskell-cafe] Climbing up the shootout...

2008-09-22 Thread Bulat Ziganshin
Hello Isaac,

Monday, September 22, 2008, 11:49:30 PM, you wrote:

 i mean that naive haskell code is very slow and 3 or 5 or twelve libs
 can't solve the problem of ghc generating slow code

 Is there something particularly fascinating about naive code written in
 any language? 

yes, in asm number of instructions executed more or less define
number of CPU cycles used. C known as portable asm. Haskell was
developed with goal to hide implementation details from egg-headed
scientists and this obviously should have some drawbacks


-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: Re[8]: [Haskell-cafe] Climbing up the shootout...

2008-09-22 Thread Jonathan Cast
On Tue, 2008-09-23 at 00:20 +0400, Bulat Ziganshin wrote:
 Hello Isaac,
 
 Monday, September 22, 2008, 11:49:30 PM, you wrote:
 
  i mean that naive haskell code is very slow and 3 or 5 or twelve libs
  can't solve the problem of ghc generating slow code
 
  Is there something particularly fascinating about naive code written in
  any language? 
 
 yes, in asm number of instructions executed more or less define
 number of CPU cycles used.

On modern processors (RISC design), naive asm is likely to be
extraordinarily slow, because memory usage and cache considerations and
register scheduling dominate processor cycles.

 C known as portable asm.

Known as != is.  And naive C is also extraordinarily slow, especially if
written at a high level.  It is not the least bit difficult to write
memory hogs in C.  (I should know; I've done it.  And so has every major
software house (including open source projects) to release in C, for
that matter.)

 Haskell was
 developed with goal to hide implementation details from egg-headed
 scientists and this obviously should have some drawbacks

Should != is.  Not all shoot-out entries look like C with Haskell syntax
(although some do).  Naive Haskell can be 100s of times slower than
well-tuned C; naive C can be 100s of times slower than well-tuned
Haskell (where well-tuned Haskell can just mean using good data
structures.  It's quite naive indeed to dismiss better data structures
and better algorithms (especially where `better algorithms) as
`libraries.)

jcc


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: having fun with GADT's

2008-09-22 Thread Anatoly Yakovenko
 data Nat a where
Z :: Nat a
S :: Nat a - Nat (S a)

 data Z
 data S a

I thought I was getting this, but this part is confusing.  What
exactly does declaring data Z do?
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re[10]: [Haskell-cafe] Climbing up the shootout...

2008-09-22 Thread Bulat Ziganshin
Hello Jonathan,

Tuesday, September 23, 2008, 12:30:19 AM, you wrote:

 yes, in asm number of instructions executed more or less define
 number of CPU cycles used.



well, i more or less know all this stuff. but are you really compare
to Haskell??? does Haskell programs typically written in account of
cache misses and CPU ticks? i suggest you to look into two papers i
mentioned - they state hundreds times slower naive Haskell vs naive C.
it's a reality, against all your arguments


-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Line noise

2008-09-22 Thread Andrew Coppin

Stephan Friedrichs wrote:

Andrew Coppin wrote:
  

[...]
- Variable names such as x and f aren't fabulously helpful to lost
programmers trying to find their way.



I'm not a fan of cryptic variable names, either, and I try to use
descriptive names wherever I can. But in Haskell...

 - ... you often have variables, which have a scope of far less than a
   line such as in map (\(x, (_, y)) - (x, y) ... (cleaning
   intermediate results from a list).

 - ... things often get very abstract, so that it just feels wrong
   matching on, say, (socket:sockets) instead of (x:xs).

  


...so, more or less the reason why mathematical formulas usually end up 
with non-descriptive variable names then. ;-)


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Line noise

2008-09-22 Thread Andrew Coppin

Ketil Malde wrote:

The rationale for having long names is that you have too many names,
and too large a scope to keep track of them all in your head.  Needing
long names is a symptom that your code is too complex, and that you
should refactor it.
  


Well, yeah. In Haskell, functions tend to be rather shorter than in 
procedural languages, so there's less call for dissambiguation because 
there are fewer variables in scope.



The other problem with descriptive names is that it is not
automatically checked by the compiler, and thus it often ends up being
misleading.  Incorrect documentation is worse than no documentation.
  


That's true enough.


Nobody is going to realise that [x] means a list.



And C is utterly incomprehensible, since from my Pascal background, I
just *know* that curly braces denote comments.  Come on, expecting
somebody to understand a language without an extremely basic
understanding of fundamental syntactical constructs is futile.
  


Point taken. I still think List x would have been clearer, but nobody 
is going to change the Haskell Report now...



well you can see why people are getting lost! ;-)



Yes, by refusing to adapt to any syntax but the single one they know.
  


Some people will glance at Haskell and think hey, that doesn't look 
like source code, I can't read that. But given the number of times I've 
explained all this stuff, you'd think one or two people would have got 
it by now...



Only if you can figure out that Map means what every other
programming language on the face of the Earth calls a
dictionary. (This took me a while!)



Except for where it is called an associative array or hash table?
Terminology is inconsistent, Haskell happens to draw more of it from
math than from other programming languages.
  


Heh, let's not argue over technical terms... ;-)

Most people seem far more confused by what a fold might be.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: having fun with GADT's

2008-09-22 Thread Frank Wilson
Someone could probably give a better explanation but I'll give this a  
shot! :)


What you are actually doing is defining a family of types. Every  
value in the
type Nat a has it's own type. For instance Z has type Nat Z, (S  
Z) or one

has type Nat (S Z),  (S (S Z)) has type Nat (S (S Z)) and so on.

In effect types Z and (S a) defined in those data declarations are  
marker types.


It might help you understand if you change the names of the types in  
the data

declarations to something else. It helps not to get confused between
types and constructors ;) .

I hope this was helpful,

Frank

On 22 Sep 2008, at 21:42, Anatoly Yakovenko wrote:


data Nat a where
  Z :: Nat a
  S :: Nat a - Nat (S a)

data Z
data S a


I thought I was getting this, but this part is confusing.  What
exactly does declaring data Z do?
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: Re[10]: [Haskell-cafe] Climbing up the shootout...

2008-09-22 Thread Jonathan Cast
On Tue, 2008-09-23 at 00:46 +0400, Bulat Ziganshin wrote:
 Hello Jonathan,
 
 Tuesday, September 23, 2008, 12:30:19 AM, you wrote:
 
  yes, in asm number of instructions executed more or less define
  number of CPU cycles used.
 
 
 
 well, i more or less know all this stuff. but are you really compare
 to Haskell???

You were tasked with finding a language where `naive' code is fast.
Assembler doesn't count; you have to think about 

  does Haskell programs typically written in account of
 cache misses and CPU ticks?

No.  At that level, you write assembler (or C).  But assembler and C are
usually not written in a naive fashion (not as naive as naive Haskell).
And when they do, they suck, performance-wise.

 i suggest you to look into two papers i
 mentioned

I don't remember the exact citation, but I'm sure I've read them.
Probably several times over.  Most papers I've seen I think the authors
looked for a large contrast; they aren't comparing Haskell and C on
truly level ground.

 - they state hundreds times slower naive Haskell

With slow datastructures

  vs naive C.

Not so naive; just better datastructures.  Which are then replicated in
the relevant papers.  And the result is neither extremely low-level code
nor 100s of times slower than C.  The term `naive' gets thrown around in
the introduction to these papers for effect, but the Haskell code under
discussion by the time you reach the conclusion isn't much less `naive'
than the C code in the introduction.

 it's a reality, against all your arguments

Bang harder!!  I don't think the next list over can hear you yet!

jcc


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] how do i use quickcheck in the IO monad?

2008-09-22 Thread Don Stewart
aeyakovenko:
 If i have functions in the IO monad, is there a way to use quickcheck
 to test them?  I have a bunch of C bindings that unfortunately are not
 safe.  But i would like to be able to use QuickCheck to test them.
 

Typically, via unsafePerformIO, and check the invariants that need to
hold for that to be safe by hand.

E.g.

prop_foo x = unsafePerformIO $ do
writeFile f x
y - readFile f
return (x == y)

-- Don
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: having fun with GADT's

2008-09-22 Thread Luke Palmer
On Mon, Sep 22, 2008 at 2:42 PM, Anatoly Yakovenko
[EMAIL PROTECTED] wrote:
 data Nat a where
Z :: Nat a
S :: Nat a - Nat (S a)

 data Z
 data S a

 I thought I was getting this, but this part is confusing.  What
 exactly does declaring data Z do?

Well, in Haskell without closed type families, it's not doing all that
much.  You could use Int or IO Elephant if you wanted to, as long as
its head is not S.  But it's documentation, because we're really
declaring the dependent type (in pseudohaskell):

data Nat
  = Z
  | S Nat

data Bounded :: Nat - * where
  BZ :: Bounded n
  BS :: Bounded n - Bounded (S n)

So Z and S are the data constructors for Nat, and Bounded *should*
only be able to take Nats as arguments.  But we cannot express that in
Haskell, we just have to be disciplined and never give anything else
to Bounded.

Luke
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Line noise

2008-09-22 Thread Jake Mcarthur

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1


Most people seem far more confused by what a fold might be.


A fold by any other name would smell as sweet. ;)
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.8 (Darwin)

iEYEARECAAYFAkjYE7kACgkQTkPEVFd3yxh7HwCfVzopoOCgg49YI0Y88g9rjXqI
DvcAn3Buv4FmqcYrK5pDLr1iUc7XRpO5
=CKiH
-END PGP SIGNATURE-
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: Re[6]: [Haskell-cafe] Climbing up the shootout...

2008-09-22 Thread Donnie Jones
Hello Bulat,

On Mon, Sep 22, 2008 at 3:09 PM, Bulat Ziganshin
[EMAIL PROTECTED]wrote:

 Hello Graham,

  i don't think that these 3 libs allows to write high-level
  high-performance code in *most* cases. just for example, try to write wc
  without using words.

  To a newbie, that's a cryptic statement. Are you saying that these
  libs aren't needed to make a high-performance wc, and that the
  Prelude functions are sufficient? (I note too that there is
  Data.ByteString.Char8.words, but I assume you are talking about the
  Prelude function.)

 i mean that naive haskell code is very slow and 3 or 5 or twelve libs
 can't solve the problem of ghc generating slow code


I'm fairly new to Haskell and the Haskell community, but I can say from my
experience of hacking on GHC, the GHC team of developers are very interested
in performance improvements, e.g. this thread is about performance!  So
Bulat, why don't you hack on GHC yourself and help improve the compiler?  Or
suggest detailed improvements since you seem capable of citing specific
examples?

Thank you.
__
Donnie
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re[8]: [Haskell-cafe] Climbing up the shootout...

2008-09-22 Thread Bulat Ziganshin
Hello Donnie,

Tuesday, September 23, 2008, 2:53:17 AM, you wrote:

 i mean that naive haskell code is very slow and 3 or 5 or twelve libs
  can't solve the problem of ghc generating slow code

 I'm fairly new to Haskell and the Haskell community, but I can say
 from my experience of hacking on GHC, the GHC team of developers are
 very interested in performance improvements, e.g. this thread is
 about performance!  So Bulat, why don't you hack on GHC yourself and
 help improve the compiler?  Or suggest detailed improvements since
 you seem capable of citing specific examples?

for the same reason i don't feed 5000 men with 7 breads - it's not my
business ;)


-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Live twittering from ICFP

2008-09-22 Thread Don Stewart
ICFP is on now, for those wondering why the list is a bit quiet :)

http://www.icfpconference.org/icfp2008/schedule.html

I'm doing live updates of events at ICFP/Haskell Symposium here in Canada.

http://twitter.com/galoisinc

So you can follow events remotely.

Cheers,
  Don
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Climbing up the shootout...

2008-09-22 Thread Don Stewart
bulat.ziganshin:
 Hello Donnie,
 
 Tuesday, September 23, 2008, 2:53:17 AM, you wrote:
 
  i mean that naive haskell code is very slow and 3 or 5 or twelve libs
   can't solve the problem of ghc generating slow code
 
  I'm fairly new to Haskell and the Haskell community, but I can say
  from my experience of hacking on GHC, the GHC team of developers are
  very interested in performance improvements, e.g. this thread is
  about performance!  So Bulat, why don't you hack on GHC yourself and
  help improve the compiler?  Or suggest detailed improvements since
  you seem capable of citing specific examples?
 
 for the same reason i don't feed 5000 men with 7 breads - it's not my
 business ;)

Ok. So I'll just say: high level, efficient code is an overriding theme
of many individuals working on Haskell. Things are better and better
each year. We do not stand still.

For example, Bulat cites a paper talking about naive list code from
2002, however, by 2008 we know how to do fusion on lists, so it runs in
the same time as low level loops, the technique is implemented and you
can download it from hackage,

http://hackage.haskell.org/cgi-bin/hackage-scripts/package/stream-fusion

Simon Marlow is busy adding more efficient GC and parallelism to GHC,
and there's a summer project to rewrite the native code generator. 
GHC gained pointer tagging in the last release cycle, dramatically
reducing the cost of algebraic data types.

At the same time, we're writing books about how to program naively in
Haskell, such that your code doesn't suck. That is: training. Teaching
people how to write Haskell.

We can see it paying off, where naive code performs very very well,

http://shootout.alioth.debian.org/gp4/benchmark.php?test=sumcollang=all

And lots and lots more people able to write good code for Hackage.

I find Bulat's outlook rather bleak, and I think it is time to update
expectations.

Progress is beautiful.

-- Don
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Climbing up the shootout...

2008-09-22 Thread Gwern Branwen
On 2008.09.22 21:12:06 +0400, Bulat Ziganshin [EMAIL PROTECTED] scribbled 
0.5K characters:
 Hello Simon,

 Monday, September 22, 2008, 9:03:52 PM, you wrote:

  With bytestrings, unboxed arrays, light-weight threads and other
  tricks, we can usually replace all those ugly low-level programs with
  nice high-level haskell ones

 i don't think that these 3 libs allows to write high-level
 high-performance code in *most* cases. just for example, try to write wc
 without using words

 --
 Best regards,
  Bulatmailto:[EMAIL PROTECTED]

http://haskell.org/haskellwiki/Wc seems to do fine; you'll notice it drops 
lines after the first version.

--
gwern
class ASPIC Duress BNC WWSV of intelligence retrieval Al PRF


signature.asc
Description: Digital signature
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re[2]: [Haskell-cafe] Climbing up the shootout...

2008-09-22 Thread Bulat Ziganshin
Hello Gwern,

Tuesday, September 23, 2008, 3:33:02 AM, you wrote:

 high-performance code in *most* cases. just for example, try to write wc
 without using words

 http://haskell.org/haskellwiki/Wc seems to do fine; you'll notice
 it drops lines after the first version.

actually it counts lines using built-in function. you may find that
naive C is 6x fatser than naive Haskell and difference is so small
only because C version is bound by memory speed


-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: Re[2]: [Haskell-cafe] Climbing up the shootout...

2008-09-22 Thread Chaddaï Fouché
2008/9/23 Bulat Ziganshin [EMAIL PROTECTED]:
 http://haskell.org/haskellwiki/Wc seems to do fine; you'll notice
 it drops lines after the first version.

 actually it counts lines using built-in function. you may find that
 naive C is 6x fatser than naive Haskell and difference is so small
 only because C version is bound by memory speed

So what ? Strings represented as lists of character are slow ? What an
incredible discovery !

The ByteString versions are fast, ByteString was invented especially
for IO intensive situation, it's a library you can use pretty naively
and mostly get excellent performances, what exactly isn't Haskelly
enough for you in this solution ? The guts of ByteString aren't
idiomatic Haskell ? And ? The guts of the JVM aren't written in Java
either... At least ByteString was built over GHC which means it can be
done.

Besides a part of the performances of ByteString comes from stream
fusion and that's specifically something that is hard to achieve
outside of Haskell...


What exactly is your point ?
- Haskell is slow, we can't make it faster ? That's obviously false as
demonstrated by the progress in the latest years.
- Haskell is slower than C ? Well that's probably true, because C can
touch the hardware directly and can always optimize every single
aspects of a computation... On the other hand that kind of uber
optimization has a cost that I am unwilling to pay, I would rather
write high level Haskell and pay a little hit on execution time.
- We shouldn't center ourselves around performance to promote Haskell
(or should we even promote Haskell) ? Well there you may have a point,
but maybe it would be better to just make it and avoid denying other
peoples efforts to make Haskell faster ?

-- 
Jedaï
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Climbing up the shootout...

2008-09-22 Thread Don Stewart
bulat.ziganshin:
 when gcc developers will start to add to C libraries functions
 performing shootout benchmarks we will continue this discussion :D

atoi(3).

-- Don
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re[2]: [Haskell-cafe] Climbing up the shootout...

2008-09-22 Thread Bulat Ziganshin
Hello Don,

Tuesday, September 23, 2008, 4:22:19 AM, you wrote:

 bulat.ziganshin:
 when gcc developers will start to add to C libraries functions
 performing shootout benchmarks we will continue this discussion :D

 atoi(3).

it isn't the same as readInt which was added specifically for this
test. it doesn't support arbitrary-size streams and doesn't return
rest of stream


-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Climbing up the shootout...

2008-09-22 Thread Don Stewart
bulat.ziganshin:
 Hello Don,
 
 Tuesday, September 23, 2008, 4:22:19 AM, you wrote:
 
  bulat.ziganshin:
  when gcc developers will start to add to C libraries functions
  performing shootout benchmarks we will continue this discussion :D
 
  atoi(3).
 
 it isn't the same as readInt which was added specifically for this
 test. it doesn't support arbitrary-size streams and doesn't return
 rest of stream
 

Hmm? That is wrong. These functions explicitly work on arbitrarily long
lazy bytestrings, and return the rest of the stream in a pair:

readInt :: ByteString - Maybe (Int, ByteString)
readInteger :: ByteString - Maybe (Integer, ByteString)

These are the initial parts of a bytestring lexing library, more of
which is appareing in the bytestring-lex package on Hackage.

-- Don
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: Re[2]: [Haskell-cafe] Climbing up the shootout...

2008-09-22 Thread Chaddaï Fouché
2008/9/23 Bulat Ziganshin [EMAIL PROTECTED]:
 Hello Don,

 Tuesday, September 23, 2008, 4:22:19 AM, you wrote:

 bulat.ziganshin:
 when gcc developers will start to add to C libraries functions
 performing shootout benchmarks we will continue this discussion :D

 atoi(3).

 it isn't the same as readInt which was added specifically for this
 test. it doesn't support arbitrary-size streams and doesn't return
 rest of stream

Yeah, readInt has a more useful type than atoi() in most circumstances
so obviously it's a default which somehow disqualify this function...
(I wasn't aware that this function was only useful in the shoutout
context, I should probably scrap it from my other programs now)

I think we should write all the entries in Haskell98 and disable any
optimisation in GHC too, that would gives us a much fairer vision of
Haskell current performances.

-- 
Jedaï
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Line noise

2008-09-22 Thread Brian Hurt



On Sun, 21 Sep 2008, wren ng thornton wrote:

Even with functionalists ---of the OCaml and SML ilk--- 
this use of spaces can be confusing if noone explains that function 
application binds tighter than all operators.


Bwuh?  Ocaml programmers certainly know that application binds tighter 
than operators.  And as:


let f x y = ... in
f a b

is more efficient (in Ocaml) than:

let f (x, y) = ... in
f (a, b)

(Ocaml doesn't optimize away the tuple allocation), the former 
(Haskell-like) is generally preferred by Ocaml programmers.


SML programmers do use the second form, I'll grant you.

Brian

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re[2]: [Haskell-cafe] Climbing up the shootout...

2008-09-22 Thread Bulat Ziganshin
Hello Don,

Tuesday, September 23, 2008, 4:36:55 AM, you wrote:

 it isn't the same as readInt which was added specifically for this
 test. it doesn't support arbitrary-size streams and doesn't return
 rest of stream
 

 Hmm? That is wrong. These functions explicitly work on arbitrarily long
 lazy bytestrings, and return the rest of the stream in a pair:

lazy bytestring which is read from file on demand is the same as
arbitrary-sized stream. equivalent C code would be much faster (and
probably limited by memory speed)

 readInt :: ByteString - Maybe (Int, ByteString)
 readInteger :: ByteString - Maybe (Integer, ByteString)

 These are the initial parts of a bytestring lexing library, more of
 which is appareing in the bytestring-lex package on Hackage.

readInt was added to FPS library by you and immediately used to
improve speed of this benchmark two years ago. there was no
readInteger since shootout doesn't contain such benchmarks :)


-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re[4]: [Haskell-cafe] Climbing up the shootout...

2008-09-22 Thread Bulat Ziganshin
Hello Chaddaï,

Tuesday, September 23, 2008, 4:39:18 AM, you wrote:

 it isn't the same as readInt which was added specifically for this
 test. it doesn't support arbitrary-size streams and doesn't return
 rest of stream

 I think we should write all the entries in Haskell98 and disable any
 optimisation in GHC too, that would gives us a much fairer vision of
 Haskell current performances.

well, it's what C developers does. just look at full list of C and
Haskell entries for this benchmark - all qualified C programs used std
C/C++ libs, several really optimized entries was disqualified. and
then Don found genious solution to the problem - add this function to
GHC libs. or shootout wasn't first usage of this function?


-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: Re[2]: [Haskell-cafe] Climbing up the shootout...

2008-09-22 Thread Sterling Clover
At the risk of getting sucked into a silly discussion, I'd like to point out
that the c code uses the following really simple and naive function:

http://sourceware.org/cgi-bin/cvsweb.cgi/libc/stdlib/strtol.c?rev=1.42.2.2content-type=text/x-cvsweb-markupcvsroot=glibc


http://sourceware.org/cgi-bin/cvsweb.cgi/libc/stdlib/strtol_l.c?rev=1.4.2.3content-type=text/x-cvsweb-markupcvsroot=glibc

Oh, and it simply and naively loops with the following:

while (fgets_unlocked (line, MAXLINELEN, stdin))

If Bulat's point is that the shootout has inspired work on Haskell
performance, and in the stdlibs no less, then lovely, and that's all to the
good. Below every high level interface is lots of low level pain.

If his point is anything else, this is getting absurd.

--S

On Mon, Sep 22, 2008 at 8:16 PM, Bulat Ziganshin
[EMAIL PROTECTED]wrote:

 Hello Don,

 Tuesday, September 23, 2008, 3:12:37 AM, you wrote:

  for the same reason i don't feed 5000 men with 7 breads - it's not my
  business ;)

  Ok. So I'll just say: high level, efficient code is an overriding theme
  of many individuals working on Haskell. Things are better and better
  each year. We do not stand still.

 yes. when we say that things are greatly improving each year, this
 means that they was bad previously ;)

  For example, Bulat cites a paper talking about naive list code from
  2002, however, by 2008 we know how to do fusion on lists, so it runs in
  the same time as low level loops, the technique is implemented and you
  can download it from hackage,

  http://hackage.haskell.org/cgi-bin/hackage-scripts/package/stream-fusion

 someone can ask why this great code isn't used in ghc by default.
 probably it is just work in progress which isn't yet ready to replace
 old slow code. then we can see tha fusion isn't magic wand which
 improves speed of every haskell code that's slower than C one. it just
 makes C-speed code sometimes

  Simon Marlow is busy adding more efficient GC and parallelism to GHC,
  and there's a summer project to rewrite the native code generator.

 well, i'm sais about *current* real situation. if you consider this as
 attack against Haskell developers, it's your mistake. the problem is
 that i many years wrote about slowness of ghc code, every time you
 cosider this as attack and write that in future Haskell will become
 much faster. we still wait for this future, however

  GHC gained pointer tagging in the last release cycle, dramatically
  reducing the cost of algebraic data types.

 10-20% speed improvement, on average. it's the only real improvement
 (for my own program) i know. i think that ByteString-related libs
 gived more improvements but their use isn't automatic and they doesn't
 help in any situation. they just provide fast library code for solving
 some concrete (although very frequent) situations, such as counting
 lines

  At the same time, we're writing books about how to program naively in
  Haskell, such that your code doesn't suck. That is: training. Teaching
  people how to write Haskell.

 it is what i say - if naive code was effective and automagically
 optimized by ghc, we don't need all those tutorials. anyone looked
 into your tutorial on writing efficient Haskell code, will never say
 that it's easier than in C. so we can conclude that optimized haskell
 programs are several times slower than C ones and need several times
 more to write

  We can see it paying off, where naive code performs very very well,

  http://shootout.alioth.debian.org/gp4/benchmark.php?test=sumcollang=all

 yes! it's my beloved example of elegant haskell code entirely based
 on the readInt function added to ghc libs specifically to win in this
 test. it's implementation is really simple and naive:

 -- -
 -- Reading from ByteStrings

 -- | readInt reads an Int from the beginning of the ByteString.  If there
 is no
 -- integer at the beginning of the string, it returns Nothing, otherwise
 -- it just returns the int read, and the rest of the string.
 readInt :: ByteString - Maybe (Int, ByteString)
 readInt as
| null as   = Nothing
| otherwise =
case unsafeHead as of
'-' - loop True  0 0 (unsafeTail as)
'+' - loop False 0 0 (unsafeTail as)
_   - loop False 0 0 as

where loop :: Bool - Int - Int - ByteString - Maybe (Int,
 ByteString)
  STRICT4(loop)
  loop neg i n ps
  | null ps   = end neg i n ps
  | otherwise =
  case B.unsafeHead ps of
w | w = 0x30
  w = 0x39 - loop neg (i+1)
  (n * 10 + (fromIntegral w - 0x30))
  (unsafeTail ps)
  | otherwise - end neg i n ps

  end _0 _ _  = Nothing
  end True _ n ps = Just (negate n, ps)
  end __ n ps = Just (n, ps)



 when gcc 

Re: [Haskell-cafe] Line noise

2008-09-22 Thread Jason Dagit
On Mon, Sep 22, 2008 at 6:27 PM, Brian Hurt [EMAIL PROTECTED] wrote:


 On Sun, 21 Sep 2008, wren ng thornton wrote:

 Even with functionalists ---of the OCaml and SML ilk--- this use of spaces
 can be confusing if noone explains that function application binds tighter
 than all operators.

 Bwuh?  Ocaml programmers certainly know that application binds tighter than
 operators.  And as:

let f x y = ... in
f a b

 is more efficient (in Ocaml) than:

let f (x, y) = ... in
f (a, b)

 (Ocaml doesn't optimize away the tuple allocation), the former
 (Haskell-like) is generally preferred by Ocaml programmers.

That's odd.  My experience from trying to learn ocaml at one point was
that the tuple notation is preferable because you can do pattern
matching on every value in the tuple whereas with the other one you
can match on either the first or second parameter but not both without
nesting ocaml's version of 'case ... of' (match ... with?).  One of
the things I really like about Haskell syntax is that you can pattern
match on any number of parameters without having to nest 'case ... of'
expressions.

Jason
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Is there already an abstraction for this?

2008-09-22 Thread Jeremy Shaw
Hello,

I am trying to figure out if there is an existing abstraction I am
missing here.

I have an expression data-type:

 data Expr 
= Quotient Expr Expr
| Product Expr Expr
| Sum Expr Expr
| Difference Expr Expr
| Lit Double
| Var Char
  deriving (Eq, Ord, Data, Typeable, Read, Show)


And I want to write a function that will take an expression and
automatically apply the identity laws to simplify the expression.

The basic identity laws are:

 a + 0 = a
 a * 1 = a

I can implement these with some 'sugar' as:

 identity (Sum (Lit 0) a)= a
 identity (Sum a (Lit 0))= a
 identity (Difference a (Lit 0)) = a
 identity (Product a (Lit 1))= a
 identity (Product (Lit 1) a)= a
 identity (Quotient a (Lit 1))   = a
 identity a  = a

This works fine when the identity only needs to be applied to the root
of the expression tree:

*Main ppExpr $ identity (expr 1 + 0)
1

But for more complicated trees it does not fully apply the identity laws:

*Main ppExpr $ identity (expr 0 + (0 + 0) + (0 + 0))
((0 + 0) + (0 + 0))

What we need to do is first apply the identity function to the
children, and then apply them to the parent of the updated children. A
first attempt would be to extend the identity function like this:

 identity (Sum a b)  = identity (Sum (identity a) (identity b))

However, that will not terminate because that same case will keep
matching over and over. Another approach is to have two mutually
recursive functions like:

 identity' (Sum (Lit 0) a)= identityRec a
 identity' (Sum a (Lit 0))= identityRec a
 identity' a = a

 identityRec (Sum a b) = identity' (Sum (identity' a) (identity' b))

This prevents non-termination, but you have to be careful about
calling identity' vs identityRec or you will either re-introduce
non-termination, or you may not fully apply the identity laws.

Another option to create a helper function like:

 -- |Deep map of an expression.
 eMap :: (Expr - Expr) - Expr - Expr
 eMap f (Sum a b) = f (Sum (eMap f a) (eMap f b))
 eMap f (Difference a b) = f (Difference (eMap f a) (eMap f b))
 eMap f (Product a b) = f (Product (eMap f a) (eMap f b))
 eMap f (Quotient a b) = f (Quotient (eMap f a) (eMap f b))
 eMap f (Var v) = f (Var v)
 eMap f (Lit i) = f (Lit i)

Now we can easily apply the identity law recursively like:

 deepIdentity :: Expr - Expr
 deepIdentity = eMap identity

*Main ppExpr (deepIdentity (expr 0 + (0 + 0) + (0 + 0)))
0

Sweet!

But, having to write eMap out by hand like that somehow feels wrong --
as if I am missing some additional abstraction. In some respects eMap
is like a Functor, but not quite. I expect there is a way to implement
eMap using Data.Generics, which is perhaps better, but I still feel
like that is missing something?

Anyway, I just thought I would ask in case someone recognized this
pattern and could point me in the right direction. I have attached a
working example program you can play with.

I would also be interested in alternative approaches besides the ones
I outlined.

thanks!
j.
{-# LANGUAGE DeriveDataTypeable #-}

 import Control.Applicative (Applicative((*), pure), (*), (*))
 import Control.Monad (ap)
 import Data.Generics (Typeable, Data)
 import Data.List (isSuffixOf)
 import   Text.ParserCombinators.Parsec  ((|))
 import qualified Text.ParserCombinators.Parsec as P
 import qualified Text.ParserCombinators.Parsec.Expr as P
 import   Text.PrettyPrint.HughesPJ ((+))
 import qualified Text.PrettyPrint.HughesPJ as H
 import Prelude hiding (sum, product)

 data Expr 
= Quotient Expr Expr
| Product Expr Expr
| Sum Expr Expr
| Difference Expr Expr
| Lit Double
| Var Char
  deriving (Eq, Ord, Data, Typeable, Read, Show)

 instance Applicative (P.GenParser token state) where
 pure = return
 (*) = ap

 parseExpr :: P.GenParser Char st Expr
 parseExpr = P.buildExpressionParser optable (lit | var | parenExpr)
 where
   parenExpr = 
   (P.char '('  P.skipMany P.space) * parseExpr * (P.char ')'  
 P.skipMany P.space)
   optable = 
   [ [ P.Infix (P.char '/'  P.skipMany P.space  return Quotient)  
 P.AssocLeft  ]
   , [ P.Infix (P.char '*'  P.skipMany P.space  return Product)
 P.AssocRight ]
   , [ P.Infix (P.char '+'  P.skipMany P.space  return Sum)
 P.AssocRight ]
   , [ P.Infix (P.char '-'  P.skipMany P.space  return Difference) 
 P.AssocLeft  ]
   ]
   lit = 
   do d - P.try (P.many1 $ P.oneOf ('-' : '.' : ['0'..'9']))
  P.skipMany P.space
  return (Lit (read d))
   var =
   do sign - (P.char '-'  return (\x - (Product (Lit (-1)) x))) 
 | (return id)
  v - (P.upper | P.lower)
  P.skipMany P.space
  return (sign (Var v))

 expr :: String - Expr
 expr str = either (error .show) id (P.parse parseExpr str str)

 ppExpr :: Expr - H.Doc
 ppExpr (Lit i)  

Re: [Haskell-cafe] Is there already an abstraction for this?

2008-09-22 Thread Dan Weston

 I can implement these with some 'sugar' as:

 identity (Sum (Lit 0) a)= a
 identity (Sum a (Lit 0))= a
 identity (Difference a (Lit 0)) = a
 identity (Product a (Lit 1))= a
 identity (Product (Lit 1) a)= a
 identity (Quotient a (Lit 1))   = a
 identity a  = a

Why do you need mutual recursion? What's wrong with:

 identity (Sum (Lit 0) a)= identity a
  ...
 identity (Quotient a (Lit 1))   = identity a
 identity a  = a

Structural recursion ensures that this always terminates.

Dan

Jeremy Shaw wrote:

Hello,

I am trying to figure out if there is an existing abstraction I am
missing here.

I have an expression data-type:

data Expr 
   = Quotient Expr Expr

   | Product Expr Expr
   | Sum Expr Expr
   | Difference Expr Expr
   | Lit Double
   | Var Char
 deriving (Eq, Ord, Data, Typeable, Read, Show)



And I want to write a function that will take an expression and
automatically apply the identity laws to simplify the expression.

The basic identity laws are:

 a + 0 = a
 a * 1 = a

I can implement these with some 'sugar' as:


identity (Sum (Lit 0) a)= a
identity (Sum a (Lit 0))= a
identity (Difference a (Lit 0)) = a
identity (Product a (Lit 1))= a
identity (Product (Lit 1) a)= a
identity (Quotient a (Lit 1))   = a
identity a  = a


This works fine when the identity only needs to be applied to the root
of the expression tree:

*Main ppExpr $ identity (expr 1 + 0)
1

But for more complicated trees it does not fully apply the identity laws:

*Main ppExpr $ identity (expr 0 + (0 + 0) + (0 + 0))
((0 + 0) + (0 + 0))

What we need to do is first apply the identity function to the
children, and then apply them to the parent of the updated children. A
first attempt would be to extend the identity function like this:


identity (Sum a b)  = identity (Sum (identity a) (identity b))


However, that will not terminate because that same case will keep
matching over and over. Another approach is to have two mutually
recursive functions like:


identity' (Sum (Lit 0) a)= identityRec a
identity' (Sum a (Lit 0))= identityRec a
identity' a = a



identityRec (Sum a b) = identity' (Sum (identity' a) (identity' b))


This prevents non-termination, but you have to be careful about
calling identity' vs identityRec or you will either re-introduce
non-termination, or you may not fully apply the identity laws.

Another option to create a helper function like:


-- |Deep map of an expression.
eMap :: (Expr - Expr) - Expr - Expr
eMap f (Sum a b) = f (Sum (eMap f a) (eMap f b))
eMap f (Difference a b) = f (Difference (eMap f a) (eMap f b))
eMap f (Product a b) = f (Product (eMap f a) (eMap f b))
eMap f (Quotient a b) = f (Quotient (eMap f a) (eMap f b))
eMap f (Var v) = f (Var v)
eMap f (Lit i) = f (Lit i)


Now we can easily apply the identity law recursively like:


deepIdentity :: Expr - Expr
deepIdentity = eMap identity


*Main ppExpr (deepIdentity (expr 0 + (0 + 0) + (0 + 0)))
0

Sweet!

But, having to write eMap out by hand like that somehow feels wrong --
as if I am missing some additional abstraction. In some respects eMap
is like a Functor, but not quite. I expect there is a way to implement
eMap using Data.Generics, which is perhaps better, but I still feel
like that is missing something?

Anyway, I just thought I would ask in case someone recognized this
pattern and could point me in the right direction. I have attached a
working example program you can play with.

I would also be interested in alternative approaches besides the ones
I outlined.

thanks!
j.




___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Is there already an abstraction for this?

2008-09-22 Thread Dan Weston
Oops, never mind. This is just the shallow application you referred to. 
Too fast with that send button!


Dan Weston wrote:


  I can implement these with some 'sugar' as:
 
  identity (Sum (Lit 0) a)= a
  identity (Sum a (Lit 0))= a
  identity (Difference a (Lit 0)) = a
  identity (Product a (Lit 1))= a
  identity (Product (Lit 1) a)= a
  identity (Quotient a (Lit 1))   = a
  identity a  = a

Why do you need mutual recursion? What's wrong with:

 identity (Sum (Lit 0) a)= identity a
  ...
 identity (Quotient a (Lit 1))   = identity a
 identity a  = a

Structural recursion ensures that this always terminates.

Dan

Jeremy Shaw wrote:

Hello,

I am trying to figure out if there is an existing abstraction I am
missing here.

I have an expression data-type:


data Expr= Quotient Expr Expr
   | Product Expr Expr
   | Sum Expr Expr
   | Difference Expr Expr
   | Lit Double
   | Var Char
 deriving (Eq, Ord, Data, Typeable, Read, Show)



And I want to write a function that will take an expression and
automatically apply the identity laws to simplify the expression.

The basic identity laws are:

 a + 0 = a
 a * 1 = a

I can implement these with some 'sugar' as:


identity (Sum (Lit 0) a)= a
identity (Sum a (Lit 0))= a
identity (Difference a (Lit 0)) = a
identity (Product a (Lit 1))= a
identity (Product (Lit 1) a)= a
identity (Quotient a (Lit 1))   = a
identity a  = a


This works fine when the identity only needs to be applied to the root
of the expression tree:

*Main ppExpr $ identity (expr 1 + 0)
1

But for more complicated trees it does not fully apply the identity laws:

*Main ppExpr $ identity (expr 0 + (0 + 0) + (0 + 0))
((0 + 0) + (0 + 0))

What we need to do is first apply the identity function to the
children, and then apply them to the parent of the updated children. A
first attempt would be to extend the identity function like this:

identity (Sum a b)  = identity (Sum (identity a) 
(identity b))


However, that will not terminate because that same case will keep
matching over and over. Another approach is to have two mutually
recursive functions like:


identity' (Sum (Lit 0) a)= identityRec a
identity' (Sum a (Lit 0))= identityRec a
identity' a = a



identityRec (Sum a b) = identity' (Sum (identity' a) (identity' b))


This prevents non-termination, but you have to be careful about
calling identity' vs identityRec or you will either re-introduce
non-termination, or you may not fully apply the identity laws.

Another option to create a helper function like:


-- |Deep map of an expression.
eMap :: (Expr - Expr) - Expr - Expr
eMap f (Sum a b) = f (Sum (eMap f a) (eMap f b))
eMap f (Difference a b) = f (Difference (eMap f a) (eMap f b))
eMap f (Product a b) = f (Product (eMap f a) (eMap f b))
eMap f (Quotient a b) = f (Quotient (eMap f a) (eMap f b))
eMap f (Var v) = f (Var v)
eMap f (Lit i) = f (Lit i)


Now we can easily apply the identity law recursively like:


deepIdentity :: Expr - Expr
deepIdentity = eMap identity


*Main ppExpr (deepIdentity (expr 0 + (0 + 0) + (0 + 0)))
0

Sweet!

But, having to write eMap out by hand like that somehow feels wrong --
as if I am missing some additional abstraction. In some respects eMap
is like a Functor, but not quite. I expect there is a way to implement
eMap using Data.Generics, which is perhaps better, but I still feel
like that is missing something?

Anyway, I just thought I would ask in case someone recognized this
pattern and could point me in the right direction. I have attached a
working example program you can play with.

I would also be interested in alternative approaches besides the ones
I outlined.

thanks!
j.




___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe






___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: having fun with GADT's

2008-09-22 Thread Anatoly Yakovenko
 data Nat a where
Z :: Nat a
S :: Nat a - Nat (S a)

 data Z
 data S a

 n00 = Z
 n01 = S n00
 n02 = S n01
 n03 = S n02
 n04 = S n03

 data MaxList t where
   Nil :: MaxList a
   Cons :: Nat a - MaxList a - MaxList a

 a = Cons n02 $ Cons n02 $ Cons n01 $ Nil
 --- :t a gives forall a. MaxList (S (S a)) which tells you exactly
 --- what you want: elements are at least 2.

 mlTail :: forall t. MaxList t - MaxList t
 mlTail (Cons h t) = t

Is there a way to define a function that only takes a list with a max
of 1?  Because

only1 :: MaxList (S a) - String
only1 _ = only1

will work over
 a = Cons n02 $ Cons n02 $ Cons n01 $ Nil
without any problems
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Is there already an abstraction for this?

2008-09-22 Thread Sebastian Fischer

Hi Jeremy,

There are some approaches that support such generic transformations.  
The simplest is probably Uniplate by Neil Mitchell:


  http://www-users.cs.york.ac.uk/~ndm/uniplate/

The function 'rewrite' is what you are looking for. If you change the  
definition of 'identity' to:



identity (Sum (Lit 0) a)= Just a
identity (Sum a (Lit 0))= Just a
identity (Difference a (Lit 0)) = Just a
identity (Product a (Lit 1))= Just a
identity (Product (Lit 1) a)= Just a
identity (Quotient a (Lit 1))   = Just a
identity _  = Nothing


then the function 'rewrite identity :: Expr - Expr' does what you want.

Cheers,
Sebastian
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: having fun with GADT's

2008-09-22 Thread David Menendez
On Mon, Sep 22, 2008 at 10:20 PM, Anatoly Yakovenko
[EMAIL PROTECTED] wrote:

 Is there a way to define a function that only takes a list with a max
 of 1?  Because

 only1 :: MaxList (S a) - String
 only1 _ = only1

 will work over
 a = Cons n02 $ Cons n02 $ Cons n01 $ Nil
 without any problems

only1 :: MaxList (S Z) - String

If you like, you may declare

type One = S Z
type Two = S One
etc.

-- 
Dave Menendez [EMAIL PROTECTED]
http://www.eyrie.org/~zednenem/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: having fun with GADT's

2008-09-22 Thread Anatoly Yakovenko
 type One = S Z
 type Two = S One
 etc.

why does:

data Nat a where
   Z :: Nat a
   S :: Nat a - Nat (S a)

data Z
data S a

type One = S Z
n00 = Z
n01::One = S n00

give me:

test.hs:10:11:
Couldn't match expected type `One'
   against inferred type `Nat (S a)'
In the expression: S n00
In a pattern binding: n01 :: One = S n00
Failed, modules loaded: none.


or better yet, how is type S Z different from, n01 :: forall a. Nat (S a)
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Bird-style and blank lines

2008-09-22 Thread Ryan Ingram
Oops, meant to send this to the whole list.

 You can add -optL -q to your ghc command line to disable that
 behavior; blank lines will no longer be required.

  -- ryan
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: having fun with GADT's

2008-09-22 Thread Ryan Ingram
Try

n01 :: Nat One

  -- ryan

On Mon, Sep 22, 2008 at 8:10 PM, Anatoly Yakovenko
[EMAIL PROTECTED] wrote:
 type One = S Z
 type Two = S One
 etc.

 why does:

 data Nat a where
   Z :: Nat a
   S :: Nat a - Nat (S a)

 data Z
 data S a

 type One = S Z
 n00 = Z
 n01::One = S n00

 give me:

 test.hs:10:11:
Couldn't match expected type `One'
   against inferred type `Nat (S a)'
In the expression: S n00
In a pattern binding: n01 :: One = S n00
 Failed, modules loaded: none.


 or better yet, how is type S Z different from, n01 :: forall a. Nat (S a)
 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Bird-style and blank lines

2008-09-22 Thread Paulo Tanimoto
On Mon, Sep 22, 2008 at 11:27 PM, Ryan Ingram [EMAIL PROTECTED] wrote:
 Oops, meant to send this to the whole list.

 You can add -optL -q to your ghc command line to disable that
 behavior; blank lines will no longer be required.

This little gem that Ryan found was exactly what I was looking for,
thank you again, Ryan.  So this is already possible in GHC, which is
what I use.  The question now is whether this is relevant enough to be
brought to the attention of people discussing Haskell Prime.  If you
think it is, let me know, I'll see what I have to do about it.

I'll update the Wiki with this information.

Thanks everybody,

Paulo
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Updated formlets sample?

2008-09-22 Thread Chris Eidhof
Ah yes, I just adjusted the code until it compiled, I must confess I  
didn't check whether it actually worked ;). Thanks for the wiki-update!


-chris

On 22 sep 2008, at 09:47, Martin Huschenbett wrote:


Hi Chris,

you're absolutely right. The mistake was in the where-part of  
withForm. The function handleOk' gets an environment d as argument  
but uses an extractor that was created without passing d to  
runFormState. I've put a corrected version on hpaste [1] and also  
posted it to the wiki on haskell.org [2]. Hope this is ok for you?


Regards,

Martin.

[1] http://hpaste.org/10568#a1
[2] http://haskell.org/haskellwiki/Formlets

Chris Eidhof schrieb:
That means that you don't have input0 in your environment, maybe  
you're passing in an empty environment?

-chris
On 21 sep 2008, at 12:11, Martin Huschenbett wrote:

Hi Chris,

thanks for the updated example. Compiling works now. But when I  
try to run it I alway get error messages like


[input0 is not in the data,input1 is not in the data]

Regards,

Martin.

Chris Eidhof schrieb:

Hey Martin,
On 19 sep 2008, at 04:14, Martin Huschenbett wrote:
I found a blog post concerning formlets [1] in the web. Since  
looks very interesting I tried to compile the sample code with  
recent versions of HAppS and formlets from hackage. But this  
didn't work as the API of formlets has changed since this post.


I tried to adopt the code to the new API but I was unable to  
finish this since there is a new monadic context I don't know to  
handle in the right way.


So my question is, is there an updated version of this sample  
code in the web or has anybody tried to adopt it and can send me  
the results?
Yes, I'm sorry for that. The API is still very immature and due  
to changes, that's also why it hasn't been officially announced  
yet. I've just put an updated example at http://hpaste.org/10568,  
hope that'll work for you. I guess we should build a small  
homepage / wikipage that always has an up-to-date example.

-chris


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Is there already an abstraction for this?

2008-09-22 Thread Nicolas Pouillard
Excerpts from Jeremy Shaw's message of Mon Sep 22 18:46:22 -0700 2008:
 Hello,
 
 I am trying to figure out if there is an existing abstraction I am
 missing here.

You can try to pick some information in the mocac [1] project, that is for
OCaml.

 
  Moca is a general construction functions generator for Caml data types with
  invariants.

  Moca supports two kinds of relations:

  * algebraic relations (such as associativity or commutativity of a
binary constructor),
  * general rewrite rules that map some pattern of constructors and
variables to some arbitrary user's define expression.
 

[1]: http://moca.inria.fr/eng.htm

Best regards,

 I have an expression data-type:
 
  data Expr 
 = Quotient Expr Expr
 | Product Expr Expr
 | Sum Expr Expr
 | Difference Expr Expr
 | Lit Double
 | Var Char
   deriving (Eq, Ord, Data, Typeable, Read, Show)
 
 
 And I want to write a function that will take an expression and
 automatically apply the identity laws to simplify the expression.
 
 The basic identity laws are:
 
  a + 0 = a
  a * 1 = a
 
 I can implement these with some 'sugar' as:
 
  identity (Sum (Lit 0) a)= a
  identity (Sum a (Lit 0))= a
  identity (Difference a (Lit 0)) = a
  identity (Product a (Lit 1))= a
  identity (Product (Lit 1) a)= a
  identity (Quotient a (Lit 1))   = a
  identity a  = a
 
 This works fine when the identity only needs to be applied to the root
 of the expression tree:
 
 *Main ppExpr $ identity (expr 1 + 0)
 1
 
 But for more complicated trees it does not fully apply the identity laws:
 
 *Main ppExpr $ identity (expr 0 + (0 + 0) + (0 + 0))
 ((0 + 0) + (0 + 0))
 
 What we need to do is first apply the identity function to the
 children, and then apply them to the parent of the updated children. A
 first attempt would be to extend the identity function like this:
 
  identity (Sum a b)  = identity (Sum (identity a) (identity b))
 
 However, that will not terminate because that same case will keep
 matching over and over. Another approach is to have two mutually
 recursive functions like:
 
  identity' (Sum (Lit 0) a)= identityRec a
  identity' (Sum a (Lit 0))= identityRec a
  identity' a = a
 
  identityRec (Sum a b) = identity' (Sum (identity' a) (identity' b))
 
 This prevents non-termination, but you have to be careful about
 calling identity' vs identityRec or you will either re-introduce
 non-termination, or you may not fully apply the identity laws.
 
 Another option to create a helper function like:
 
  -- |Deep map of an expression.
  eMap :: (Expr - Expr) - Expr - Expr
  eMap f (Sum a b) = f (Sum (eMap f a) (eMap f b))
  eMap f (Difference a b) = f (Difference (eMap f a) (eMap f b))
  eMap f (Product a b) = f (Product (eMap f a) (eMap f b))
  eMap f (Quotient a b) = f (Quotient (eMap f a) (eMap f b))
  eMap f (Var v) = f (Var v)
  eMap f (Lit i) = f (Lit i)
 
 Now we can easily apply the identity law recursively like:
 
  deepIdentity :: Expr - Expr
  deepIdentity = eMap identity
 
 *Main ppExpr (deepIdentity (expr 0 + (0 + 0) + (0 + 0)))
 0
 
 Sweet!
 
 But, having to write eMap out by hand like that somehow feels wrong --
 as if I am missing some additional abstraction. In some respects eMap
 is like a Functor, but not quite. I expect there is a way to implement
 eMap using Data.Generics, which is perhaps better, but I still feel
 like that is missing something?
 
 Anyway, I just thought I would ask in case someone recognized this
 pattern and could point me in the right direction. I have attached a
 working example program you can play with.
 
 I would also be interested in alternative approaches besides the ones
 I outlined.
 
 thanks!
 j.
 {-# LANGUAGE DeriveDataTypeable #-}
 
  import Control.Applicative (Applicative((*), pure), (*), (*))
  import Control.Monad (ap)
  import Data.Generics (Typeable, Data)
  import Data.List (isSuffixOf)
  import   Text.ParserCombinators.Parsec  ((|))
  import qualified Text.ParserCombinators.Parsec as P
  import qualified Text.ParserCombinators.Parsec.Expr as P
  import   Text.PrettyPrint.HughesPJ ((+))
  import qualified Text.PrettyPrint.HughesPJ as H
  import Prelude hiding (sum, product)
 
  data Expr 
 = Quotient Expr Expr
 | Product Expr Expr
 | Sum Expr Expr
 | Difference Expr Expr
 | Lit Double
 | Var Char
   deriving (Eq, Ord, Data, Typeable, Read, Show)
 
  instance Applicative (P.GenParser token state) where
  pure = return
  (*) = ap
 
  parseExpr :: P.GenParser Char st Expr
  parseExpr = P.buildExpressionParser optable (lit | var | parenExpr)
  where
parenExpr = 
(P.char '('  P.skipMany P.space) * parseExpr * (P.char ')'  
  P.skipMany P.space)
optable = 
[ [ P.Infix (P.char '/'  P.skipMany P.space  return Quotient) 
   P.AssocLeft  ]
, [ P.Infix (P.char '*'  P.skipMany P.space  return Product)  

[Haskell-cafe] what is the magic hash?

2008-09-22 Thread Jason Dusek
  It is not much covered in the docs. It has something to do
  with magic triggered by a postfix octothorpe?

--
_jsn

 |...docs.|
  http://haskell.org/ghc/docs/latest/html/users_guide/flag-reference.html
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] what is the magic hash?

2008-09-22 Thread Derek Elkins
On Mon, 2008-09-22 at 21:58 -0700, Jason Dusek wrote:
 It is not much covered in the docs. It has something to do
   with magic triggered by a postfix octothorpe?

All it does is allow them in identifiers.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] what is the magic hash?

2008-09-22 Thread Jason Dusek
Derek Elkins [EMAIL PROTECTED] wrote:
 Jason Dusek wrote:
 It is not much covered in the docs. It has something to do
   with magic triggered by a postfix octothorpe?

 All it does is allow them in identifiers.

  That's it? So it's for use in conjunction with primitive
  types, I guess (those seem to be denoted like 'Int#')?

  With the fancy name and the absence of documentation, I
  assumed it must be really special.

--
_jsn
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: having fun with GADT's

2008-09-22 Thread David Menendez
On Mon, Sep 22, 2008 at 11:10 PM, Anatoly Yakovenko
[EMAIL PROTECTED] wrote:
 type One = S Z
 type Two = S One
 etc.

 why does:

 data Nat a where
   Z :: Nat a
   S :: Nat a - Nat (S a)

 data Z
 data S a

 type One = S Z
 n00 = Z
 n01::One = S n00

 give me:

 test.hs:10:11:
Couldn't match expected type `One'
   against inferred type `Nat (S a)'
In the expression: S n00
In a pattern binding: n01 :: One = S n00
 Failed, modules loaded: none.


 or better yet, how is type S Z different from, n01 :: forall a. Nat (S a)


In short, S Z is a type and n01 is a value.

One point that's important to keep in mind is that types and data
constructors have disjoint namespaces, so you can have a type Z and a
data constructor Z which do not need to have any connection.

It may be clearer if we rename the data constructors for Nat.

data Z
data S n

type One = S Z

data Nat :: * - * where
Zero :: Nat Z
Succ :: Nat n - Nat (S n)

one :: Nat One
one = Succ Zero

Similarly, One is a type (One :: *) and one is a value (one :: Nat One
and Nat One :: *).

Note also that Z and S are declared here as empty types, using a
common extension. That means there are no (non-bottom) values that
have type Z or S a. This means that Z and S are only used as arguments
to other type constructors or in class contexts.

As long as we're discussing type-level naturals, you may find this old
post of mine interesting.

http://www.haskell.org/pipermail/haskell/2005-May/015815.html

-- 
Dave Menendez [EMAIL PROTECTED]
http://www.eyrie.org/~zednenem/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe