Re: [Haskell-cafe] is there some book about haskell and data struct and alg?

2008-05-31 Thread Robert Dockins

[snip]
  Without the equivalent Haskell source code, the code must be manually
  translated from Standard ML into Haskell.  Does anybody know why the link
  is broken, when it may be fixed, and from where the Haskell source code
  can be currently obtained?
 
  Benjamin L. Russell

 If you are interested in the topic, you will probably want to check out
 Edison: http://www.cs.princeton.edu/~rdockins/edison/home/.

 I believe some of the older code in there was even written by Okasaki.

Indeed, the vast majority of the code was written by Okasaki. Most of the data 
structures from his book are in Edison.

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


Re: [Haskell-cafe] Longest increasing subsequence

2008-04-10 Thread Robert Dockins
On Thursday 10 April 2008 01:20:49 pm Matt Amos wrote:
 I'm trying to break out of my imperative mind-set by learning Haskell
 in small snippets. After a few successes I've hit a bit of a
 roadblock with one of the classic dynamic programming problems, the
 longest increasing subsequence:

 http://en.wikipedia.org/wiki/Longest_increasing_subsequence

 The most efficient algorithm relies on destructive updates, so a
 simple translation doesn't seem possible. I've been trying to think of
 a way of removing the need for destructive updates while keeping the
 efficiency, but so far without much luck. Ideally, I'd like to avoid
 threading the whole thing with a state monad, since then it would
 just be an imperative algorithm in disguise.

 Any suggestions would be very gratefully appreciated.

Memorization is a nice way to implement dynamic programming algorithms in 
Haskell.  Basically, you arrange it so that the underlying runtime does the 
destructive updates for you.

http://www.haskell.org/haskellwiki/Memoization


 Cheers,

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


Re: [Haskell-cafe] Re: (flawed?) benchmark : sort

2008-03-13 Thread Robert Dockins
On Thursday 13 March 2008 07:33:12 pm Aaron Denney wrote:

[snip]
 I've seen mention of difficulties with Data.Map, and edison, but not
 in enough detail to really grasp what the problems are.  Until I do, my
 natural bias (which I'm trying to resist, really) is that it's a matter
 of lazy coding, not any inherent difficulty.

For the specific case of Edison, the Haddock documentation for the following 
two modules tells the whole sordid story:

http://hackage.haskell.org/packages/archive/EdisonAPI/1.2.1/doc/html/Data-Edison.html
http://hackage.haskell.org/packages/archive/EdisonAPI/1.2.1/doc/html/Data-Edison-Coll.html

The Cliff Notes version is that Edison assumes the following things about Eq 
and Ord instances:

*  An Eq instance correctly defines an equivalence relation (but not 
necessarily structural equality); that is, we assume (==) (considered as a 
relation) is reflexive, symmetric and transitive, but allow that equivalent 
items may be distinguishable by other means.
* An Ord instance correctly defines a total order which is consistent with the 
Eq instance for that type. 

It's not explicitly stated, but Edison also assumes that the operations within 
a class are consistent, i.e., that (not (x == y)) calculates the same 
function as (x /= y), etc.  I suppose that should go in the docs too.  Edison 
makes no particular assumptions about min and max, except that they are 
consistent with the defined order.

Anyway, the end result for Edison is that some operations aren't well-defined, 
and can't be made well-defined without restrictions.  For example, consider 
the operation of folding in non-decreasing order over the elements of a 
multi-set.  If the function being folded distinguishes between two elements x 
and y, but (compare x y) = EQ, and x and y are both contained in the 
multi-set, then the result of the fold depends on internal state that is not 
supposed to be user-visible (e.g., the exact shape of a balanced tree).

Blah, blah, blah, its all in the documentation.  The point is that making 
loose assumptions about the meaning of the operations provided by Eq and Ord 
complicates things in ways that can't be made to go away.


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


Re: [Haskell-cafe] Doubting Haskell

2008-02-16 Thread Robert Dockins
I'm going to try to respond the the main practical question in this message; 
perhaps others will feel up to addressing the more philosophical aspects.

(I see now that Cale has beaten me to the punch, but I guess I'll post this 
anyways...)

 Greetings Haskellers,
[snip quite a bit of discussion]

 Great. Next, translate the bit that
 says (pseudocode):

   if(attempt_file_open)
 if(attempt_file_read)
   process

 That's it. No fancy, complex error messages. Just check the error
 returns and only proceed if I have something to proceed with. Like
 grown-ups do. I *will* check my error returns. I have tormented too
 many newbies to *ever* consider doing anything else. If I cannot check
 my error returns I will not write the program.

You'll find in Haskell that the normal way of handling things like I/O errors 
is to use the exception handling mechanism.  There aren't usually error 
returns to check.  Instead you usually place error handlers at the positions 
where you want to be notified of errors using the catch or handle 
functions.  If you want to you can convert any IO action into one with an 
error return by using the try function.  The Control.Exception module is 
probably the one you want to check out.

http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Exception.html

[snip more discussion]

 If so, 
 I sincerely suggest an example or two, like the small but well formed
 programs in KR, Stroustrup or Gosling saying things like:

   if((fp = fopen(...)) != NULL)
   {
 if(fgets(...) != NULL)
 {
   printf(...);
 }

 fclose(...)
   }

Here is a quick example I whipped up.  It includes both a pretty direct 
translation of the above code, and another version which is a little more 
idiomatic.

Rob Dockins

--- code follows 
import Control.Exception
import System.IO


main = direct_translation

direct_translation = do
  tryh - try (openFile test.txt ReadMode)
  case tryh of
Left err - print err
Right h - do
   tryl - try (hGetLine h)
   case tryl of
 Left err - do print err; hClose h
 Right l - do
 putStrLn l
 hClose h
  
the_way_I_would_do_it = handle (\err - print err) $
  bracket (openFile test.txt ReadMode) hClose $ \h - do
 l - hGetLine h
 putStrLn l
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell] New releases for Edison, Shellac, and the Lambda Shell

2007-12-04 Thread Robert Dockins
Fellow Haskellers,

The following packages have now all been updated to compile correctly with GHC 
6.8.x and Cabal 1.2.x.  Cabal 1.2 is now supported and required.  GHC 6.6.x 
and 6.8.x are supported.

I would also like to announce that these projects are now hosted from a new 
web home.  If you have bookmarks or automated build systems that point to 
older versions of these packages, please update them to point to the new 
locations listed below.  The old website will not dissapear, but it will no 
longer be updated.  Thank you!



Edison 1.2.1.1

Edison is a library of purely function data structures for Haskell.

Project homepage:
http://www.cs.princeton.edu/~rdockins/edison/home/

Hackage:
http://hackage.haskell.org/cgi-bin/hackage-scripts/package/EdisonAPI-1.2.1
http://hackage.haskell.org/cgi-bin/hackage-scripts/package/EdisonCore-1.2.1.1




Shellac 0.9.1

Shellac is a framework for building read-eval-print style shells.  Shells are 
created by declaratively defining a set of shell commands and an evaluation 
function.

Project homepage:
http://www.cs.princeton.edu/~rdockins/shellac/home/

Hackage:
http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Shellac-0.9.1
http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Shellac-readline-0.9




Lambda Shell 0.9.1

The Lambda Shell is a feature-rich shell environment and command-line tool for 
evaluating terms of the pure, untyped lambda calculus. The Lambda Shell 
builds on the shell creation framework Shellac, and showcases most of 
Shellac's features.

Project homepage:
http://www.cs.princeton.edu/~rdockins/lambda/home/

Hackage:
http://hackage.haskell.org/cgi-bin/hackage-scripts/package/LambdaShell-0.9.1
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell-cafe] Collections library

2007-11-28 Thread Robert Dockins
[snip]

 I recently withdrew from this project and offered up the libs I'd been
 working on as they are for a new owner. Didn't get any takers though
 (no surprises there!). I've always found the lack of apparent interest
 in all this somewhat puzzling myself. It's not as if there's no latent 
 demand for efficient collections. (Data.Map is probably the most
 regularly whined about of all the standard libs.)

FWIW, I find the same phenomenon with Edison.  I get very little feedback 
about it positive or negative; I really have no idea how many people are 
using it.  I guess people are more willing to roll their own data structures 
or use the standard libs.

It might be from a desire to limit dependencies.  If that's the case, perhaps 
continuing cabal developments will change that.

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


Re: [Haskell-cafe] Type without a data constructor?

2007-08-06 Thread Robert Dockins
On Monday 06 August 2007 19:23, Rahul Kapoor wrote:
 Most examples for defining algebraic types include data constructors like
 so:

 data Tree a = Tip | Node a (Tree a) (Tree a)

 I by mistake defined a type which did not specify a data constructor :

In this example, you have two different uses of the lexical name 'Term', and I 
think it is confusing you.  One kind of use is as a data constructor; the 
other is as a type constructor.  I've annotated the uses below:

 data SearchCondition
 = Term Bool-- data constructor
 | SearchCondition :||: (Term Bool)-- type constructor

 data Term a = Constant a  -- defn of type constr 'Term'

 sc :: SearchCondition
 sc = Term True -- data constructor

 is ok, but

 sc :: SearchCondition
 sc = Constant True  
 
Now, here you have an expression of type 'Term Bool'.  These can only appear 
on the right-hand side of :||: .  This probably isn't what you want.  Likely 
what you actually want is:

 data SearchCondition
 = SearchTerm (Term Bool) | SearchCondition :||: (Term Bool) 

Here, both uses of 'Term' refer to the type constructor.



 is not (though this is what I intended to capture!).

 So the question is what are types with no constructors good for? A
 simple example would be appreciated.

There are some situations where an explicitly empty type is useful.  
Type-level programming voodoo is one.

Other times the void type is nice because it can be used as a parameter to a 
type constructor.  For example, if you use the nested datatype representation 
of de Bruijn lambda terms [1], you can use the void type to create the type 
of closed terms (terms with no free variables).  Here's the short version:

data Void
data Succ a = Zero | Incr a
data Term a = Var a | App (Term a) (Term a) | Lam (Term (Succ a))
type ClosedTerm = Term Void



[1] Richard Bird and Ross Patterson, _de Brujin Notation as a Nested 
Datatype_, Journal of Functional Programming 9(1):77-91, January 1999.


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


Re: [Haskell-cafe] Re: Can we do better than duplicate APIs? [was: Data.CompactString 0.3]

2007-03-28 Thread Robert Dockins


On Mar 28, 2007, at 2:44 PM, Benjamin Franksen wrote:


Robert Dockins wrote:
After taking a look at the Haddock docs, I was impressed by the  
amount of
repetition in the APIs. Not ony does Data.CompactString duplicate  
the

whole
Data.ByteString interface (~100 functions, adding some more for  
encoding
and decoding), the whole interface is again repeated another four  
times,

once for each supported encoding.


I'd like to mention that as maintainer of Edison, I face similar

difficulties.
The data structure interfaces have scores of functions and there  
are about

20
different concrete implementations of various sorts.  Even minor  
interface

changes require a lot of tedious editing to make sure that everything

stays

in sync.


But... you have the type of all functions nailed down in classes.  
Thus, even
if a change in the API means a lot of tedious work adapting the  
concrete

implementations, at least the compiler helps you to check that the
implementations will conform to the interface (class);


This is true.


and users have to
consult only the API docs, and not every single function in all 20
implementations. With ByteString and friends there is (yet) no common
interface laid down anywhere. All the commonality is based on  
custom and
good sense and the willingness and ability of the developers to  
make their

interfaces compatible to those of others.


One could use code
generation or macro expansion to alleviate this, but IMO the  
necessity to
use extra-language pre-processors points to a weakness in the  
language;

it
be much less complicated and more satisfying to use a language  
feature

that

avoids the repetition instead of generating code to facilitate it.


I've considered something like this for Edison.  Actually, I've  
considered
going even further and building the Edison concrete  
implementations in a

theorem prover to prove correctness and then extracting the Haskell

source.

Some sort of in-langauge or extra-language support for mechanicly

producing
the source files for the full API from the optimized core API  
would be

quite welcome.  Handling export lists,


How so? I thought in Edision the API is a set of type classes.  
Doesn't that

mean export lists can be empty (since instances are exported
automatically)?


No.  Edison allows you to directly import the module and bypass the  
typeclass APIs if you wish.  Also, some implementations have special  
functions that are not part of the general API, and are only  
available via the module exports.


One could make typeclasses the only way to access the main API, but I  
rather suspect there would be performance implications.  I get the  
impression that typeclass specialization is less advanced than  
intermodule inlining (could be wrong though).




haddock comments,


I thought all the documentation would be in the API classes, not in  
the

concrete implementations.


It is now, but I've gotten complaints about that (which are at least  
semi-justified, I feel).  Also, the various implementations have  
different time bounds which must documented in the individual  
modules.  Ideally, I'd like to have the function documentation string  
and the time bounds on each function in each concrete  
implementation.  I've not done this because its just too painful to  
maintain manually.




typeclass instances,
etc, are quite tedious.

I have to admit, I'm not sure what an in-language mechanism for doing
something like this would look like.  Template Haskell is an  
option, I
suppose, but its pretty hard to work with and highly non- 
portable.  It

also
wouldn't produce Haddock-consumable source files.  ML-style first  
class

modules might fit the bill, but I'm not sure anyone is seriously

interested

in bolting that onto Haskell.


As I explained to SPJ, I am less concerned with duplicated work when
implementing concrete data structures, as with the fact that there  
is still
no (compiler checkable) common interface for e.g. string-like  
thingies,

apart from convention to use similar names for similar features.



Fair enough.  I guess my point is that typeclasses (ad per Edison)  
are only a partial solution to this problem, even if you can stretch  
them sufficiently (with eg, MPTC+fundeps+whatever other extension) to  
make them cover all your concrete implementations.




Cheers
Ben



Rob Dockins

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



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


Re: [Haskell-cafe] Re: Can we do better than duplicate APIs?

2007-03-28 Thread Robert Dockins
On Wednesday 28 March 2007 17:08, Benjamin Franksen wrote:
 Robert Dockins wrote:
  Some sort of in-langauge or extra-language support for mechanicly
 
  producing
 
  the source files for the full API from the optimized core API
  would be
  quite welcome.

 Have you considered using DrIFT? IIRC it is more portable and easier to use
 than TH.

DrIFT only works on datatype declarations (AFAIK) and doesn't really cover the 
use cases in question.

[snip]

  haddock comments,
 
  I thought all the documentation would be in the API classes, not in
  the
  concrete implementations.
 
  It is now, but I've gotten complaints about that (which are at least
  semi-justified, I feel).  Also, the various implementations have
  different time bounds which must documented in the individual
  modules.

 Yes, I forgot about that. Hmmm.

  Ideally, I'd like to have the function documentation string
  and the time bounds on each function in each concrete
  implementation.  I've not done this because its just too painful to
  maintain manually.

 I can relate to that. The more so since establishing such time bounds with
 confidence is not trivial even if the code looks simple. BTW, code
 generation (of whatever sort) wouldn't help with that, right?

Well, I can't imagine any tool that would prove the bounds for me unless 
automatic proof techniques have improved a _lot_ in the last week or so ;-)

However, if I could record the bounds once somewhere for each implementation 
and then have them auto merged with the documentation for each function, that 
would be great.

 I wonder: would it be worthwhile to split the package into smaller parts
 that could be upgraded in a somewhat less synchronous way? (so that the
 maintenance effort can be spread over a longer period)

Perhaps, but that only amortizes the effort rather than reducing it.


[snip]

  As I explained to SPJ, I am less concerned with duplicated work when
  implementing concrete data structures, as with the fact that there
  is still
  no (compiler checkable) common interface for e.g. string-like
  thingies,
  apart from convention to use similar names for similar features.
 
  Fair enough.  I guess my point is that typeclasses (ad per Edison)
  are only a partial solution to this problem, even if you can stretch
  them sufficiently (with eg, MPTC+fundeps+whatever other extension) to
  make them cover all your concrete implementations.

 Yes, and I think these problems would be worth some more research effort.

Agreed.

 Besides, I dearly hope that we can soon experiment with associated type
 synonyms...

 Cheers
 Ben


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


Re: [Haskell-cafe] Can we do better than duplicate APIs? [was: Data.CompactString 0.3]

2007-03-24 Thread Robert Dockins
On Friday 23 March 2007 18:55, Benjamin Franksen wrote:
 [sorry for the somewhat longer rant, you may want to skip to the more
 technical questions at the end of the post]

 Twan van Laarhoven wrote:
  I would like to announce version 0.3 of my Data.CompactString library.
  Data.CompactString is a wrapper around Data.ByteString that represents a
  Unicode string. This new version supports different encodings, as can be
  seen from the data type:
 
  [...]
 
  Homepage:  http://twan.home.fmf.nl/compact-string/
  Haddock:   http://twan.home.fmf.nl/compact-string/doc/html/
  Source:darcs get http://twan.home.fmf.nl/repos/compact-string

 After taking a look at the Haddock docs, I was impressed by the amount of
 repetition in the APIs. Not ony does Data.CompactString duplicate the whole
 Data.ByteString interface (~100 functions, adding some more for encoding
 and decoding), the whole interface is again repeated another four times,
 once for each supported encoding.

I'd like to mention that as maintainer of Edison, I face similar difficulties.  
The data structure interfaces have scores of functions and there are about 20 
different concrete implementations of various sorts.  Even minor interface 
changes require a lot of tedious editing to make sure that everything stays 
in sync.

[snip]

 The problems I (for-)see are for maintenance and usability, both of which
 are of course two sides of the same coin. For the library implementer,
 maintenance will become more difficult, as ever more of such 'almost equal'
 interfaces must be maintained and kept in sync.

This is true. For the specific case of Edison, this is not too bad because all 
the implementations are currently in one package and under the control of one 
person (namely, me).  That might, however, change in the future.  Obviously, 
it is a problem _now_ for the ByteString and friends.

 One could use code 
 generation or macro expansion to alleviate this, but IMO the necessity to
 use extra-language pre-processors points to a weakness in the language; it
 be much less complicated and more satisfying to use a language feature that
 avoids the repetition instead of generating code to facilitate it.

I've considered something like this for Edison.  Actually, I've considered 
going even further and building the Edison concrete implementations in a 
theorem prover to prove correctness and then extracting the Haskell source.  
Some sort of in-langauge or extra-language support for mechanicly producing 
the source files for the full API from the optimized core API would be 
quite welcome.  Handling export lists, haddock comments, typeclass instances, 
etc, are quite tedious.

I have to admit, I'm not sure what an in-language mechanism for doing 
something like this would look like.  Template Haskell is an option, I 
suppose, but its pretty hard to work with and highly non-portable.  It also 
wouldn't produce Haddock-consumable source files.  ML-style first class 
modules might fit the bill, but I'm not sure anyone is seriously interested 
in bolting that onto Haskell.

[snip]

 Here are some raw ideas:

 One reason why I think type classes have not (yet) been used to reduce the
 amount of API repetition is that Haskell doesn't (directly) support
 abstraction over type constraints nor over the number of type parameters
 (polykinded types?). Often such 'almost equal' module APIs differ in
 exactly these aspects, i.e. one has an additional type parameter, while yet
 another one needs slightly different or additional constraints on certain
 types. Oleg K. has shown that some if these limitations can be overcome w/o
 changing or adding features to the language, however these tricks are not
 easy to learn and apply.

I mostly put these kinds of type system tricks in the same category as TH: 
hard to use and non-portable.

[snip]

 Or maybe we have come to the point where Haskell's lack of a 'real' module
 system, like e.g. in SML, actually starts to hurt? Can associated types
 come to the rescue?

I'm not familiar enough with associated types to know if they would help with 
these sorts of problems.  Can someone more knowledgable comment?

 Cheers
 Ben


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


Re: strict bits of datatypes

2007-03-20 Thread Robert Dockins


On Mar 20, 2007, at 9:53 AM, Malcolm Wallace wrote:


Ian Lynagh [EMAIL PROTECTED] wrote:


data Fin a = FinCons a !(Fin a) | FinNil
w = let q = FinCons 3 q
in case q of
   FinCons i _ - i

is w 3 or _|_?


Knowing that opinions seem to be heavily stacked against my
interpretation, nevertheless I'd like to try one more attempt at
persuasion.

The Haskell Report's definition of `seq` does _not_ imply an order of
evaluation.  Rather, it is a strictness annotation.  (Whether this is
the right thing to do is another cause of dissent, but let's accept  
the

Report as is for now.)  So `seq` merely gives a hint to the compiler
that the value of its first argument must be established to be
non-bottom, by the time that its second argument is examined by the
calling context.  The compiler is free to implement that guarantee in
any way it pleases.

So just as, in the expression
x `seq` x
one can immediately see that, if the second x is demanded, then the
first one is also demanded, thus the `seq` can be elided - it is
semantically identical to simply
x

Now, in the definition
x = x `seq` foo
one can also make the argument that, if the value of x (on the lhs of
the defn) is demanded, then of course the x on the rhs of the defn is
also demanded.  There is no need for the `seq` here either.
Semantically, the definition is equivalent to
x = foo
I am arguing that, as a general rule, eliding the `seq` in such a case
is an entirely valid and correct transformation.

The objection to this point of view is that if you have a definition
x = x `seq` foo
then, operationally, you have a loop, because to evaluate x, one must
first evaluate x before evaluating foo.  But as I said at the  
beginning,

`seq` does _not_ imply order of evaluation, so the objection is not
well-founded.



I just want to say that the argument I find most convincing is the  
'least fixpoint' argument, which does not at all require assumptions  
about order of evaluation.


I see your arguments as something along the lines the non-bottom  
answer is a fixpoint of the equations, and therefore it is the  
correct answer.  And, it is in fact _a_ fixpoint; but it is not the  
_least_ fixpoint, which would be bottom.


To recap, the equation in question is:

q = seq q (RealFinCons 3 q)


It is not hard to see that q := _|_ is a fixpoint.

Also, we have that q := LUB( _|_, RealFinCons 3 _|_, RealFinCons 3  
(RealFinCons 3 _|_), ... ) is a fixpoint and is  _|_.


But that doesn't matter since _|_ is the least element of the domain  
and must therefore be the least fixpoint.





Regards,
Malcolm



Rob Dockins

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



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


Re: [Haskell-cafe] what I learnt from my first serious haskell programm

2007-03-19 Thread Robert Dockins


On Mar 19, 2007, at 9:56 AM, Henning Thielemann wrote:



On Mon, 19 Mar 2007, Fawzi Mohamed wrote:

A practice I've seen a lot in small- to mid-sized programs is to  
have

a Types module that contains definitions of the types used in the
program.


ok I will think about it


I'd avoid that and suggest a more decentralized design, where each  
module

contributes one main type and according functions.


I'd just like to mention that I've used the central Types module  
myself on occasion.  The main reason is to avoid the need for  
mutually recursive modules, and not because its a particularly nice  
design.  I try to arrange the user-visible API around some coherent  
organizing principle, such as the one Henning proposes, but that  
sometimes leads to module dependency cycles; factoring out a Types  
module is one way to break the cycles.




Rob Dockins

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



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


Re: [Haskell-cafe] Church Encoding Function

2007-03-10 Thread Robert Dockins
On Saturday 10 March 2007 09:43, Joachim Breitner wrote:
 Hi,

 some more ideas following from the last post. I noticed how the function
 Data.Maybe.maybe converts a Haskell Maybe into a Church encoded Maybe.
 Also, the if construct, interpreted as a function, converts a Bool into
 a church encoded Bool.

 If lists are encoded as forall b. (a - b - b) - b - b, then foldr,
 with the right order of arguments, converts a haskell [] to a Church
 encoded List.

 Is there a name for these functions? “Characteristic Church Encoding
 Functions” maybe? Are there more than these:

I believe these are the same as catamorphisms.

http://en.wikipedia.org/wiki/Catamorphism

Here is the paper where the term (AFAIK) was coined (although I have to admit 
to having only skimmed it):

http://citeseer.ist.psu.edu/meijer91functional.html


I'm pretty sure you can define a catamorphism for any regular algebraic data 
type.  I'm not 100% sure what the story is for non-regular (AKA nested) 
datatypes.


 Maybe -- maybe
 Bool -- ifthenelse
 List -- foldr
 (,) -- uncurry

 Just a short idea while waiting at the airport...

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


Re: [Haskell] How does do know when to stop?

2007-02-15 Thread Robert Dockins


On Feb 15, 2007, at 4:15 PM, Rob Hoelz wrote:

When I define a function and I use do to string functions together,  
how
does it know when my list of functions has come to an end?  For  
example:


foo = do
bar
baz
other_func
bar = ...

How does it know to stop at other_func?

Thanks,
Rob Hoelz



'do' blocks are subject to the layout rule. See:

http://en.wikibooks.org/wiki/Haskell/Indentation


The short version is that it notices when a line is less indented,  
and that ends the do block.




Rob Dockins

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



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


Re: [Haskell-cafe] pythags

2007-02-12 Thread Robert Dockins


On Feb 12, 2007, at 11:02 AM, [EMAIL PROTECTED] wrote:


Hello,

the Advanced Monads page in the Haskell Wikibook
(http://en.wikibooks.org/wiki/Haskell/Advanced_monads) contains the  
following

example of a List Monad

pythags = do
x - [1..]
y - [x..]
z - [y..]
guard (x^2 + y^2 == z^2)
return (x, y, z)

However, whenever you load that function definition into Hugs or  
GHCi, you get a

message saying that guard is an undefined variable.

Does anyone know why?

Thanks.

phiroc



Add the line


import Control.Monad


to the beginning of your program.  The 'guard' function is not  
automatically in scope.





Rob Dockins

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



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


Re: [Haskell-cafe] pythags

2007-02-12 Thread Robert Dockins


On Feb 12, 2007, at 11:02 AM, [EMAIL PROTECTED] wrote:


Hello,

the Advanced Monads page in the Haskell Wikibook
(http://en.wikibooks.org/wiki/Haskell/Advanced_monads) contains the  
following

example of a List Monad

pythags = do
x - [1..]
y - [x..]
z - [y..]
guard (x^2 + y^2 == z^2)
return (x, y, z)

However, whenever you load that function definition into Hugs or  
GHCi, you get a

message saying that guard is an undefined variable.

Does anyone know why?

Thanks.

phiroc



Another note about this function -- it doesn't actually work.  It  
will forever try increasing values of z, trying to find a z such that  
z^2 = 1^2 + 1^2, and no such z exists.  The following function,  
however, does seem to correctly generate all the Pythagorean triples.



pythags = do
   z - [1..]
   x - [1..z]
   y - [x..z]
   guard (x^2 + y^2 == z^2)
   return (x,y,z)






Rob Dockins

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



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


Re: [Haskell-cafe] questions about core

2007-02-12 Thread Robert Dockins


On Feb 12, 2007, at 1:31 PM, Kirsten Chevalier wrote:


On 2/11/07, Matt Roberts [EMAIL PROTECTED] wrote:
  - Exactly what are the operational and denotational semantics of  
core?


Since I don't think this question has been answered yet, here's a
mailing list post from  Simon PJ that probably answers it:
http://www.haskell.org/pipermail/glasgow-haskell-users/2003- 
February/004849.html


That's from 2003, but I don't think the answer has changed since then.
If you wrote down a precise operational and/or denotational semantics
for Core, you'd probably have a research paper. (Especially if you
proved that GHC actually obeys that semantics...) (Disclaimer: my name
isn't Simon.)


At the risk of sounding self-promoting, I'd like to point out that  
the research paper I recently announced defines an intermediate  
language that is similar to GHC's core in some respects (they are  
both based on System F_omega).  I give a full (call-by-name)  
operational semantics and type system for the language in my report  
[1].  You won't find any proofs in the paper, but they're on my  
medium-term agenda.  There is also source code for an interpreter/ 
bytecode-compiler/shell for this intermediate language [2].


[1] http://www.cs.tufts.edu/tr/techreps/TR-2007-2
[2] http://www.eecs.tufts.edu/~rdocki01/masters.html



Cheers,
Kirsten




Rob Dockins

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



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


[Haskell] Announce: Bytecode Verification for Haskell

2007-02-11 Thread Robert Dockins
Fellow Haskellers,

I am very pleased to announce that I recently completed the degree 
requirements for my master's.  As a part of those requirements, I undertook 
research that may be of interest to those of you subscribed to this list.  My 
research involved designing and implementing a type verification algorithm 
for Yhc Haskell bytecode.

The final report detailing this research may found at the Tufts CS Department 
technical reports page [1]. The abstract for the report follows this message.  
In addition to the report, I have made available the source code for my 
proof-of-concept implementation, which consists of a simple bytecode compiler 
and verifier.  The source code may be found at the project page for this 
research [2].

If you have questions or comments please either email me directly or take 
discussion to the haskell-cafe or yhc mailing lists.

Thanks,
Rob Dockins


[1] http://www.cs.tufts.edu/tr/techreps/TR-2007-2
[2] http://www.eecs.tufts.edu/~rdocki01/masters.html




Abstract:

In this paper we present a method for verifying Yhc bytecode, an intermediate 
form of Haskell suitable for mobile code applications. We examine the issues 
involved with verifying Yhc bytecode programs and we present a 
proof-of-concept bytecode compiler and verifier.

Verification is a static analysis which ensures that a bytecode program is 
type-safe. The ability to check type-safety is important for mobile code 
situations where untrusted code may be executed. Type-safety subsumes the 
critical memory-safety property and excludes important classes of exploitable 
bugs, such as buffer overflows. Haskell's rich type system also allows 
programmers to build effective, static security policies and enforce them 
using the type checker. Verification allows us to be confident the 
constraints of our security policy are enforced.
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell-cafe] factorising to prime numbers

2007-02-09 Thread Robert Dockins


On Feb 9, 2007, at 9:20 AM, Dougal Stanton wrote:


Hi folks,

I recently read in my copy of Concrete Mathematics the relationship
between prime factors powers and lcm/gcd functions. So I decided to
reimplement gcd and lcm the long way, for no other reason than because
I could.

If you look at the definition of 'powers' you'll note it's  
infinite. So

there's no easy way to take the product of this list, if I don't know
how many items to take from it.

Is there a better way to turn an integer N and a list of primes
[p1,p2,p3,...] into powers [c1,c2,c3,...] such that

N = product [p1^c1, p2^c2, p3^c3, ...]

If I'm missing something really obvious I'll be very grateful. I can't
really work out what kind of structure it should be. A map? fold?


If I've understood correctly your list 'powers' will be all zeros  
after a certain point.  Once that happens, you don't need to examine  
that part of the list anymore.  This should at least occur as soon as  
the primes become larger than your number N (and probably sooner.   
sqrt(N) maybe? I forget).  So, you should be able to only examine a  
prefix of the list 'primes'.  The definition you have looks right, in  
that it correctly generates the correct list.  If you want to test  
that its doing the right thing, you can just examine the prefix:


 test n = product (zipWith (^) (takeWhile (n) primes) (powers n))

(untested, but I think it would work).

or you can just create the portion of the powers list you need in the  
first place:



 powersPrefix n = map (f n) (takeWhile (n) primes)



(remember kids, a decidable problem is a semi-decidable problem where  
we can calculate a stopping condition).




D.


-- Concrete Mathematics
-- Graham, Knuth  Patashnuk

module Concrete where

import Data.List

-- the sieve of eratosthenes is a fairly simple way
-- to create a list of prime numbers
primes =
let primes' (n:ns) = n : primes' (filter (\v - v `mod` n /= 0)  
ns)

in primes' [2..]

-- how many of the prime p are in the unique factorisation
-- of the integer n?
f 0 _ = 0
f n p | n `mod` p == 0 = 1 + f (n `div` p) p
  | otherwise = 0

powers n = map (f n) primes

--gcd :: Integer - Integer - Integer
--gcd = f . map (uncurry min)

--
Dougal Stanton




Rob Dockins

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



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


Re: [Haskell-cafe] List operation question

2007-02-04 Thread Robert Dockins
On Sunday 04 February 2007 14:24, Nicolas Frisby wrote:
 I've always thought that when certain operations are of particular
 interest, it's time to use more appropriate data structures, right?
 Lists are great and simple and intuitive, but if you need such
 operations as shifts, something like a deque is the way to go.

 I'm not a data structure pro, but I'm sure someone on this list could
 post a neat example. Or you could look for work by Osaki - he seems to
 be the reference for functional data structures. Finger trees and
 tries also get a lot of attention around here.


Also, take a look at Edison.  It has a variety of sequence implementations 
with different properties.  Several of them have efficient access to both 
ends of the sequence.


http://www.eecs.tufts.edu/~rdocki01/edison.html


 Enjoy.

 On 2/4/07, Lennart Augustsson [EMAIL PROTECTED] wrote:
  Not much better.  You could define shiftl such that is does a single
  traversal and
  returns both the last element and all but the last.  That will save
  you one traversal.
 
  On Feb 4, 2007, at 18:44 , Eric Olander wrote:
   Hi,
  I'm still somewhat new to Haskell, so I'm wondering if there are
   better ways I could implement the following functions, especially
  
   shiftl:
moves the first element to the end of the list
  
   shiftr :: [a] - [a]
   shiftr [] = []
   shiftr (x:y) = y ++ [x]
  
moves the last element to the head of the list
  
   shiftl :: [a] - [a]
   shiftl [] = []
   shiftl x = [last x] ++ init x
  
   -Eric
   ___
   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

 ___
 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] Replacing [a] with (Set c a) in Monad instance.

2007-01-30 Thread Robert Dockins
On Tuesday 30 January 2007 20:06, Bryan Donlan wrote:
 Daniel McAllansmith wrote:
  Hello.
 
  Given:
 
  newtype Dist a = D {unD :: [(a,Int)]}
 
  instance Monad Dist where
return x = D [(x,1)]
d = f  = D [(y,q*p) | (x,p) - unD d, (y,q) - unD (f x)]
fail _   = D []
 
 
  How would one change Dist to wrap an instance of the (Data.Edison.Set c
  a) typeclass so that the Monad instance could be implemented in terms of
  e.g. singleton, unionWith, empty, etc?

 I don't know about Data.Edison.Set, but if it's anything like
 base/Data.Set, then there's an Ord constraint on the elements, making it
 impossible to directly transform into a monad.

There are several flavors of set typeclasses in Edison.  Some have Ord 
constraints and some don't.  All of them have an Eq constraint, however, so 
the objection still applies.  Furthermore, Edison collection classes are 
organized as types of kind *, whereas monad instances require kind * - *.

http://www.eecs.tufts.edu/~rdocki01/docs/edison/Data-Edison-Coll.html


If you instead want to replace your list with one of the Edison sequence 
implementations, that should be possible.  However, I'm not really sure that 
it's going to buy you a lot.  From a quick glance, it looks like the regular 
list type is going to be the best datastructure for the computational pattern 
of this monad, as long as your computations are sufficiently lazy.



 However, Roberto Zunino 
 came up with a clever way to bypass this problem with GADTS:
 http://article.gmane.org/gmane.comp.lang.haskell.cafe/18118

 You may be able to apply this to your situation, using various Edison
 collections depending on which typeclasses your monad argument implements.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Channel9 Interview: Software Composability and the Future of Languages

2007-01-30 Thread Robert Dockins
On Tuesday 30 January 2007 19:02, Bulat Ziganshin wrote:
 Hello Tim,

 Saturday, January 27, 2007, 10:23:31 PM, you wrote:
  Humm.  While I can accept that this is a valid criticism of Haskell's
  monadic structure for dealing with I/O, I fail to see how it could drive
  a decision to prefer an imperative language like C#, where every
  statement has this property (overspecification of evaluation order).
 
  True.. perhaps his objection was related to having a bulky syntax (one

 on *practice*, C++ compilers can reorder statements. are this true for
 Haskell compilers?

Well... I think most reordering occurs very late in the process, during 
instruction selection.  These reorderings are very fine-grained, very local 
in scope and are really only (supposed to be!) done when the reordering can 
be shown to have no affect on the outcome of the computation.  I'd be very 
surprised to see a C or C++ compiler reordering something like function 
calls.  (Although, with gcc I believe there's a flag where you can explicitly 
mark a function as being side-effect free.  I can see a compiler perhaps 
moving calls to such functions around.  But really, how's that any better 
than what we've got in Haskell?).

Caveat: I have only a passing knowledge of the black art of C/C++ compiler 
construction, so I could be wrong.


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


[Haskell-cafe] Re: Fixed-point operator (was: seq does not preclude parametricity)

2007-01-28 Thread Robert Dockins
On Sunday 28 January 2007 23:19, Matthew Brecknell wrote:
 On Wed, 24 Jan 2007 10:41:09 -0500, Robert Dockins wrote:
  newtype Mu a = Roll { unroll :: Mu a - a }
 
  omega :: a
  omega = (\x - (unroll x) x) (Roll (\x - (unroll x) x))
 
  fix :: (a - a) - a
  fix f = (\x - f . (unroll x) x) (Roll (\x - f . (unroll x) x)) omega
 
  ones :: [Int]
  ones = fix (1:)
 
  fibs :: [Int]
  fibs = fix (\f a b - a : f b (a+b)) 0 1

 That's an interesting definition of fix that I haven't seen before,
 though I am a little puzzled by omega. Since I have an irrational fear
 of recursion, and I like to take every opportunity I get to cure it, I
 decided to take a closer look...

 I figure omgea is just a way to write _|_ as an anonymous lambda
 expression.

Yup.  If you type-erase it, you get the very familiar term:

(\x - x x) (\x - x x)

Which is the canonical non-terminating untyped lambda term.

 But that made me wonder what it's doing in the definition of 
 fix.

I like to think of fix as implementing the semantics of recursion via the 
ascending Kleene chain.  Kleene's fixpoint theorem says that:

least_fixpoint( f ) = least_upper_bound (f^i  _|_   |   i in N )

where f^i means f composed together i times.

If you run it out, you'll see that my definition of fix calculates something 
like:

(f . f . f . f  ... ) _|_

===

f (f (f (f ( ... _|_


 I can see that without it, fix would have the wrong type, since 

 type inference gives the x parameters the type (Mu(b-a)):
  -- A bit like fix, except it's, erm...
  broke :: (a - a) - b - a
  broke f = (\x - f . unroll x x) (Roll (\x - f . unroll x x))

 So omega consumes an argument that has unconstrained type, and which
 appears to be unused. It's perhaps easier to see the unused argument

 with fix rewritten in a more point-full style:
  fix' f = (\x y - f (unroll x x y)) (Roll (\x y - f (unroll x x y)))
  omega

 Performing the application, (fix' f) becomes (f(fix' f)), and so on.

 So, I think I follow how this fixed-point operator works, and it seems
 reasonable to use _|_ to consume an unused non-strict argument. But I
 find it mildly disturbing that this unused argument seems to appear out
 of nowhere.

 Then I noticed that rewriting fix without (.) seems to work just as well
 (modulo non-termination of the GHC inliner), and without the unused

 argument:
  fix :: (a - a) - a
  fix f = (\x - f (unroll x x)) (Roll (\x - f (unroll x x)))

This is another fine way to write it.

 Of course, the corollary is that I can introduce as many unused

 arguments as I want:
  fix'' f = (\x - (f.).(unroll x x)) (Roll (\x - (f.).(unroll x x)))
  omega omega fix''' f = (\x - ((f.).).(unroll x x)) (Roll (\x -
  ((f.).).(unroll x x))) omega omega omega -- etc...

 This gave me a new way to approach the question of where the unused
 argument came from. Given a function (f) of appropriate type, I can

 write:
  f :: a - a
  (f.) :: (b - a) - (b - a)
  ((f.).) :: (c - b - a) - (c - b - a)

 And so on. Nothing strange here. But all of these functions can inhabit

 the argument type of fix, so:
  fix :: (a - a) - a
  fix f :: a
  fix (f.) :: b - a
  fix ((f.).) :: c - b - a

 Those are some strange types, and I have found those unused arguments
 without reference to any particular implementation of fix. Thinking
 about it, (forall a b . b - a) is no stranger than (forall a . a).
 Indeed, I think the only thing that can have type (forall a . a) is _|_.
 Likewise, I can't imagine anything other than the identity function
 having the type (forall a . a - a), and it's not too hard to see where
 (fix id) would lead.

 So perhaps it's not the appearance of the unused argument in the above
 definition of the fixed-point operator, but the type of the fixed-point
 operator in general that is a bit strange. Certainly, I have always
 found fix to be mysterious, even though I am getting quite comfortable
 with using it.

 I'm wondering: Is any of this related to the preceding discussion about
 how fix affects parametricity? Can anyone recommend some
 (preferably entry-level) readings?
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Channel9 Interview: Software Composability and the Future of Languages

2007-01-27 Thread Robert Dockins
On Friday 26 January 2007 22:14, Tim Newsham wrote:
  impractical language, only useful for research. Erik Meijer at one point
  states that programming in Haskell is too hard and compares it to
  assembly programming!

 He brings up a very good point.  Using a monad lets you deal with
 side effects but also forces the programmer to specify an exact
 ordering.  This *is* a bit like making me write assembly language

 programming.  I have to write:
 do {
x - getSomeNum
y - anotherWayToGetANum
return (x + y)
 }

 even if the computation of x and y are completely independant of
 each other.  Yes, I can use liftM2 to hide the extra work (or
 fmap) but I had to artificially impose an order on the computation.
 I, the programmer, had to pick an order.

Humm.  While I can accept that this is a valid criticism of Haskell's monadic 
structure for dealing with I/O, I fail to see how it could drive a decision 
to prefer an imperative language like C#, where every statement has this 
property (overspecification of evaluation order).  The only mainstream-ish 
general-purpose language I know of that I know of that attempts to addresses 
this problem head-on is Fortress.  (Although, to be honest, I don't know 
enough about Fortress to know how it handles I/O to even know if it is an 
actual improvement over the situation in Haskell.)


 Ok, maybe assembly language is a bit extreme (I get naming, allocation
 and garbage collection!) but it is primitive and overspecifies the
 problem.

 Tim Newsham
 http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO is not a monad

2007-01-25 Thread Robert Dockins


On Jan 25, 2007, at 6:57 AM, Yitzchak Gale wrote:


Scott Turner wrote:
Paul B. Levy's studies of call-by-push-value model strictness/ 
laziness using

a category theoretic approach.


That sounds interesting. Do you have a reference for that?


http://www.cs.bham.ac.uk/~pbl/papers/


The first sentence of the paper Call-by-push-value: Deomposing Call- 
By-Value and Call-By-Name reads:


Let us consider typed call-by-value (CBV) and typed call-by-name  
(CBN), and observe
convergence at ground type only. (This restriction does not matter in  
CBV, but in CBN,

it makes the η-law for functions into an observational equivalence.)



That sounds a lot like it explicitly excludes a polymorphic seq.   
However, I'm not very familiar with this work, so I don't know if  
that is a critical restriction, or merely incidental to the  
presentation of this paper.




Thanks,
Yitz



Rob Dockins

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



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


Re: seq does not preclude parametricity (Re: [Haskell-cafe] IO is not a monad)

2007-01-24 Thread Robert Dockins


On Jan 24, 2007, at 8:27 AM, Lennart Augustsson wrote:


Well, I think fix destroys parametricity too, and it would be better
to get rid of fix.  But I'm not proposing to do that for Haskell,
because I don't have a viable proposal to do so.  (But I think the
proposal would be along the same lines as the seq one; provide fix
in a type class so we can keep tabs on it.)
BTW, fix can be defined in the pure lambda calculus, just not in  
simply

typed pure lambda calculus (when not qualified by typed the term
lambda calculus usually refers to the untyped version).



I think its important to point out here that fix _can_ be defined in  
sufficiently rich typed lambda-calculi.  You just need unrestricted  
recursive types (iso-recursive is sufficient).  Since Haskell has  
those, you can't get rid of fix using typeclasses.  You would also  
need something like the strict positivity restriction, which is a  
pretty heavyweight restriction.



code

newtype Mu a = Roll { unroll :: Mu a - a }

omega :: a
omega = (\x - (unroll x) x) (Roll (\x - (unroll x) x))

fix :: (a - a) - a
fix f = (\x - f . (unroll x) x) (Roll (\x - f . (unroll x) x)) omega

ones :: [Int]
ones = fix (1:)

fibs :: [Int]
fibs = fix (\f a b - a : f b (a+b)) 0 1

main = print $ take 20 fibs

/code



FYI, don't try to run this in GHC, because it gives the simplifier fits.



[snip]


Rob Dockins

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



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


Re: [Haskell-cafe] Re: seq does not preclude parametricity (Re: IO is not a monad)

2007-01-24 Thread Robert Dockins
On Wednesday 24 January 2007 20:20, Stefan Monnier wrote:
  FYI, don't try to run this in GHC, because it gives the simplifier fits.

 You mean it triggers a bug in the inliner?

http://www.haskell.org/ghc/docs/latest/html/users_guide/bugs.html

Third bullet in secion 12.2.1.


I gather that GHC HQ has decided that the problem is pathological enough to 
sweep under the rug.  I can't say I blame them.  Really, the only reason to 
construct custom fixpoint combinators is to show that it can be done :-)  
Using the built-in facilities for recursion is far easier and almost 
certainly results in better code.


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


Re: [Haskell-cafe] IO is not a monad (and seq, and in general _|_)

2007-01-23 Thread Robert Dockins

On Jan 23, 2007, at 2:09 PM, Brandon S. Allbery KF8NH wrote:

Can someone explain to me, given that (a) I'm not particularly  
expert at maths, (b) I'm not particularly expert at Haskell, and  
(c) I'm a bit fuzzybrained of late:


Given that _|_ represents in some sense any computation not  
representable in and/or not consistent with Haskell,


I'm not sure you've got quite the right notion of what bottom  
means.  There are lots of computations that are representable in  
Haskell that are equivalent to _|_.  _|_ is just a name we give to  
the class of computations that don't act right (terminate).


why/how is reasoning about Haskell program behavior in the presence  
of _|_ *not* like reasoning about logic behavior in the presence of  
(p^~p)-q?


You seem to be talking around the edges of the Curry-Howard  
isomorphism.  C-H basically says that there is a correspondence  
between typed lambda calculi and some logical system.  Types  
correspond to logical formulas and lambda terms correspond to  
proofs.  However, a system like Haskell's (where every type is  
inhabited) corresponds to an inconsistent logic (one where every well- 
formed statement is provable).  That just means that the logic system  
corresponding to Haskell's type system isn't a very useful one.   
However, we don't reason _about_ Haskell using that logic, so its not  
really a problem.


Its possible, however, that I don't understand your question.  The  
formula (p^~p)-q (AKA, proof by contradiction) is valid most  
classical and constructive logics that I know of, so I'm not quite  
sure what you're getting at.




Rob Dockins

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



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


Re: [Haskell-cafe] STM and random numbers

2007-01-12 Thread Robert Dockins


On Jan 12, 2007, at 10:58 AM, Chad Scherrer wrote:


Hi,

I'd like to be able to use randomIO, but I'm working within the
context of STM. Is there a way to get these working together happily?

For now, I guess I could kludgingly use unsafePerformIO inside STM
(it's the other way around that's not allowed, right?), but I would
need to be sure it doesn't get inlined.


Humm... I'd actually suggest you stop trying to break the rules, and  
use the portion of the random interface that doesn't require IO.  You  
can pretty easily wrap a StdGen using StateT, and write your stuff in  
the monad (StateT StdGen STM).


Or, (and I'm amazed this hasn't been done before), you can create a  
custom random monad that wraps up this behavior.  Prototype  
attached.  Now you can write in (RandT StdGen STM), and use the  
convenient getRandom method.


Invoke like:

dostuff :: IO ()
dostuff = do
gen - newStdGen
x - atomically (evalRandT stuff gen)
process x

stuff :: RandT StdGen STM Int
stuff = do
 r - getRandom
 lift (someSTMaction r)




Thanks,

Chad



Rob Dockins

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




Random.hs
Description: Binary data


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


[Haskell] [ANN] Shellac 0.6, new Vty Shellac backend, Lamba Shell 0.5

2007-01-03 Thread Robert Dockins
Fellow Haskellers,

I am pleased to simultaneously announce the immediate release of the following 
related packages:

Shellac, 0.6
Shellac-readline, 0.3
Shellac-vty, 0.1

Shellac is a framework for building read-eval-print style shells which uses 
configurable backend plugins.

The major new feature of this release is the new Shellac-vty backend package, 
which uses the new Vty library (http://members.cox.net/stefanor/vty/) to do 
terminal I/O directly.  It currently has basic line editing keybindings, 
paging, and a command history.  The main package and Shellac-readline updates 
consist of minor API updates.

The project page for these packages may be found at:
http://www.eecs.tufts.edu/~rdocki01/shellac.html


Additionally, the Lambda Shell 0.5 release is now available.  The Lambda Shell 
is a shell environment for defining, evaluating and manipulating expressions 
of the pure, untyped lambda calculus.  It is also a showcase for Shellac and 
a model for its use.  This update contains little new functionality, but is 
mostly a maintaince update.

The Lambda Shell project page may be found at:
http://www.eecs.tufts.edu/~rdocki01/lambda.html


If you wish to play with the new Vty Shellac backend, you may 'darcs apply' 
the following patch to the lambda shell darcs sources before building.  It 
will cause the lambda shell to use the Vty backend rather than the readline 
backend.
http://www.eecs.tufts.edu/~rdocki01/lambda-shell-vty.patch


Thanks all and happy hacking,
Rob Dockins
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell-cafe] FD problem in GHC 6.6

2006-12-20 Thread Robert Dockins


On Dec 19, 2006, at 10:11 PM, Dan Weston wrote:


 instance CommandFunction (Sh st ()) st where
   ^
I think your first argument (on which the second has a functional  
dependence) does not determine the second argument, since it makes  
use of st in the first argument. This strikes me as a likely place  
to begin.


No, I'm pretty sure this isn't a problem.  The second argument is  
determined _because_ it is mentioned in the first.  The functional  
dependencies and instance declarations work, as long as I can make  
the compiler accept them.  They are only being rejected by the  
termination-checking part of the algorithm.


That said, I'm open to the idea of reformulating these instances.  In  
fact, I don't really like the fact that I need FDs.  It seems to me  
that I should somehow be able to eliminate the second argument  
altogether and thus the FD, but I can't seem to figure it out.



Dan

Robert wrote:

Fellow Haskellers,
I have a package that uses some light typeclass hackery to  
automaticly

build parsing algorithms based on the type of a function.
I was recently informed that my package doesn't compile on GHC 6.6  
due
to the new restrictions on FD resolution; in particular I have  
instance
declarations which fail the coverage condition.  I can use  
undecidable
instances to make the package compile again, but I'd prefer not to  
if I

can avoid it.
class CommandFunction f st | f - st where
  parseCommand  :: String - f - CommandParser st
  commandSyntax :: f - [Doc]
instance CommandFunction (Sh st ()) st where





  parseCommand wbc m str =
 -- list monad
 do (x,[]) - runRegex (maybeSpaceBefore (Epsilon  
(CompleteParse

 m))) str
return x
  commandSyntax _ = []
instance CommandFunction r st
  = CommandFunction (Int - r) st where
  parseCommand = doParseCommand Nothing intRegex id
  commandSyntax f = text (show intRegex) : commandSyntax (f  
undefined)

instance CommandFunction r st
  = CommandFunction (Integer - r) st where
  parseCommand = doParseCommand Nothing intRegex id
  commandSyntax f =  text (show intRegex) : commandSyntax (f  
undefined)







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



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


Re: [Haskell-cafe] Re: Versioning

2006-12-20 Thread Robert Dockins


On Dec 20, 2006, at 2:37 PM, Joachim Durchholz wrote:


Ross Paterson schrieb:
It might be not feasible though. The papers mention that you  
can't serialize (well, actually unserialize) function values with  
it. For the envisioned update-through-marshalling process, this  
would prevent me from ever using function values in data that  
needs to be persistent, and that's quite a harsh restriction.

That's hard to avoid, unless you have a data representation of the
functions you're interested in.


I could encode functions by their name. I don't think that would  
scale to a large application with multiple developers, but it's not  
this kind of project anyway.
I'd be reluctant to accept that way if it means adding boilerplate  
code for every function that might ever be serialized. Since I'm  
planning to serialize an entire application, I fear that I'd need  
that boilerplate code for 90% of all functions, so even a single  
line of boilerplate might be too much.


Let me just say here that what you are attempting to do sounds very  
difficult.  As I understand, you want to be able to serialize an  
entire application at some (predetermined / arbitrary?) point, change  
some of its code and/or data structures, de-serialize and run the  
thing afterwards.  Doing something like this without explicit  
language support is going to be hard, especially in a fairly static  
language like Haskell.


I would think Smalltalk, Erlang, or something from the Lisp/Scheme  
family would be more suitable for this sort of work (caveat, I have  
little experience with any of these languages).  Also, take a look  
here (http://lambda-the-ultimate.org/node/526) for some related  
discussion.





Regards,
Jo



Rob Dockins

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



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


[Haskell] [ANN] Edison 1.2.1

2006-12-16 Thread Robert Dockins

Fellow Haskellers,

I am pleased to announce the 1.2.1 release of Edison.  Edison is a  
library of efficient, purely-functional data structures in Haskell.


Notable changes from version 1.2.0.1:

* A new sequence implementation based on finger trees (similar to  
Data.Sequence in the base libs).
* Documenation fixes dealing with the licence (the docs previously  
and incorrectly claimed Edison was under the BSD licence, when it is  
in fact the MIT license).
* Added a few methods to EnumSet for wrapping and unwrapping the  
underlying Word


The project home page is: http://www.eecs.tufts.edu/~rdocki01/ 
edison.html


From here you can find source tarballs, online Haddock docs and the  
darcs repository.




Rob Dockins

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

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


Re: [Haskell-cafe] [Haskell] Defining Cg, HLSL style vectors in Haskell

2006-11-28 Thread Robert Dockins


On Nov 28, 2006, at 7:46 AM, Slavomir Kaslev wrote:


Hello,

I have to define a couple of float2, float3, float4 Cg, HLSL style
vectors in Haskell. At first I was tempted to make them instances of
Num, Floating, RealFrac, etc. but some of the functions defined in
those classes have no sense for vectors. One such example is signum
from class Num.

There are several workarounds for this. One may come up with some
meaning for vectors of such functions, for example:

instance Num Float3 where
   .
   signum a | a == Float3 0 0 0 = 0
 | otherwise = 1

This is silly. Other option, which I prefer, is to leave such
functions undefined (that is signum=undefined, not just not defining
them). Is this ok? Are there any other options?


This will work.  So long as you don't call signum, all will be well.


Another bugging thing is that some of the functions do have meaning
for vectors but they need different signatures. For example (**) ::
Floating a = a - a - a, for vectors should be (**) :: (Floating a,
Vector v) = v - a - v, that is (**) applied for every component of
the vector. Any workarounds for that?

I know that I can scrap all those Num, Floating, RealFrac, etc.
classes and define class Vector from scratch, but I really don't want
to come up and use different names for +, -, etc. that will bloat the
code.



The inflexibility of the numeric classes is one of the well-known  
problems with the definition of the Haskell prelude.  As you say,  
there are a number of things for which only a subset of the  
operations make sense, or where more general types are needed for the  
operations.  There have been a couple of attempts to reformulate  
these classes so that they are more flexible.


Here is one that I know of:
http://darcs.haskell.org/numericprelude/

I haven't used it, so I can't really comment, other than to say it  
exists.  I seem to recall that there were several other attempts in a  
similar vein, but my brief google search didn't turn them up.  Can  
someone else fill in?



If you want to roll your own, you can still use the nice names if you  
explicitly import the prelude and hide names.  Eg,


import Prelude hiding ( (+), (-),  etc  )

Hope that helps.


Last question: Does haskell have something like C++ templates? For
example, some time in the future I may need types like int2, short3,
etc., that behave just like float2, float3, but use different types
for their components. I really, really wouldn't like to copy-paste the
definitions of floatn and manually change their types to intn
respectfully.

Cheers.

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




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



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


Re: [Haskell-cafe] Collection of objects?

2006-11-17 Thread Robert Dockins


On Nov 17, 2006, at 12:36 PM, Valentin Gjorgjioski wrote:

Is some kind of collection of object with different types in  
Haskell exist? Except the tuples, which have fixed length.

I find this

   * Tuples heterogeneous, lists homogeneous.
   * Tuples have a fixed length, or at least their length is  
encoded in

 their type. That is, two tuples with different lengths will have
 different types.
   * Tuples always finite.

But I need something which is heterogeneous and non-fixed length.  
I'm used do Java, and this switch to functional languages is very  
strange to me. So, to be clear, I need something like  
LinkedListObject in java.




The thing you're looking for doesn't really exist. (OK, yes, I'm  
lying a bit.  You can use existential types, but you probably don't  
actually need them, and they can get complicated quickly; they're  
better left until later).


Can you give us more details about what you're trying to do?  
Readjusting your thinking patterns can be difficult, but the people  
on this list are usually happy to help.




Can you please help me or suggest me, what can I use in this case?

Valentin



Rob Dockins

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



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


Re: [Haskell-cafe] Re: Debugging partial functions by the rules

2006-11-15 Thread Robert Dockins


On Nov 15, 2006, at 9:48 AM, Jón Fairbairn wrote:


Simon Peyton-Jones [EMAIL PROTECTED] writes:


| The problem I see is that head/fromJust errors are usually
|caused by *beginner* Haskellers, who don't know the
|techniques for statically avoiding them.

I don't agree.  My programs have invariants that I can't
always express in a way that the type system can
understand. E.g. I know that a variable is in scope, so
searching for it in an environment can't fail:
head [ v | (n,v) - env, n==target ] (Maybe if I had
an Oleg implant I could express all this in the type system
-- but I don't.)


But instead of “blah (head [ v | (n,v) - env, n==target ])
blah”, you could write

blah the_v_in_scope blah
where (the_v_in_scope:_) =  [ v | (n,v) - env, n==target ]

and get a source-code located error message, couldn't you?
It's not very high tech, but it's what you would write if
head didn't exist, and it doesn't seem /that/ great an
imposition.


Or how about ??

lookupVarible target env =
   case [ v | (n,v) - env, n==target ] of
  (x:_) - x
  _ - assert False $ BUG: Unexpected variable out of scope ++ 
(show target)++ in environment ++(show env)



 ... lookupVariable target env 


It seems to me that every possible use of a partial function has some  
(possibly imagined) program invariant that prevents it from failing.   
Otherwise it is downright wrong.  'head', 'fromJust' and friends  
don't do anything to put that invariant in the program text.


Custom functions like the above 1) give you a great opportunity to  
add a meaningful assertion AND document the program invariant 2)  
attach some semantic meaning to the operation by naming it 3) make  
you think about what you're doing and help you avoid writing bugs in  
the first place 4) give you nice hooks for replacing your data- 
structure with a better one later, should it be necessary 5)  
encourage you to break down larger functions into smaller ones.


Big win if you ask me.  The frequent use of partial functions from  
the Prelude counters all of these advantages, and I avoid them as  
much as possible.




--
Jón Fairbairn  
[EMAIL PROTECTED]





Rob Dockins

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



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


Re: [Haskell-cafe] Re: Debugging partial functions by the rules

2006-11-15 Thread Robert Dockins
On Wednesday 15 November 2006 15:53, John Hughes wrote:
  From: Robert Dockins [EMAIL PROTECTED]
 
  It seems to me that every possible use of a partial function has some
  (possibly imagined) program invariant that prevents it from failing.
  Otherwise it is downright wrong.  'head', 'fromJust' and friends
  don't do anything to put that invariant in the program text.

 Well, not really. For example, I often write programs with command line
 arguments, that contain code of the form

 do ...
[a,b] - getArgs
...

 Of course the pattern match is partial, but if it fails, then the standard
 error message is good enough.

I'd actually put this in a different category than 'partial function' (in what 
might be regarded as an abuse of termonology).  This is failure in a monad, 
and is something I personally use a lot.  Failure in IO just usually happens 
to have behavior very similar to calling 'error'.

I'll often write code in an arbitrary monad just to model partiality via 
the 'fail' function.  Sometimes, as here, I use partial pattern matches to do 
this implicitly.  Why is this better than 'error'?  Because it allows the 
code consumer decide how to deal with problems.  You can use runIdentity to 
convert 'fail' to 'error'.  You can run with runErrorT and recover the error 
message.  You can run it in a custom moand that has some other fancy error 
handling. etc, etc.


 This applies to throw away code, of course, and if I decide to keep the
 code then I sooner or later extend it to fix the partiality and give a more
 sensible error message. But it's still an advantage to be ABLE to write the
 more concise, but cruder version initially.

I'm not against partial pattern matching.  I think it's way better than using 
partial projection functions.

 This isn't a trivial point. We know that error handling code is a major
 part of software cost--it can even dominate the cost of the correct case
 code (by a large factor). Erlang's program for the correct case strategy,
 coupled with good fault tolerance mechanisms, is one reason for its
 commercial success--the cost of including error handling code *everywhere*
 is avoided. But this means accepting that code *may* very well fail--the
 failure is just going to be handled somewhere else.

 Haskell (or at least GHC) has good exception handling mechanisms too. We
 should be prepared to use them, and let it fail when things go wrong. The
 savings of doing so are too large to ignore.

 John

-- 
Rob Dockins

Talk softly and drive a Sherman tank.
Laugh hard, it's a long way to the bank.
   -- TMBG
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Fractional/negative fixity?

2006-11-08 Thread Robert Dockins


On Nov 8, 2006, at 3:58 AM, [EMAIL PROTECTED] wrote:


Lennart Augustsson wrote:


On Nov 7, 2006, at 11:47 ,
[EMAIL PROTECTED] wrote:


Henning Thielemann wrote:

On Tue, 7 Nov 2006, Simon Marlow wrote:

I'd support fractional and negative fixity.  It's a simple  
change to

make, but we also have to adopt

[...]


I think that computable real fixity levels are useful, too. A  
further
step to complex numbers is not advised because those cannot be  
ordered.


But ordering of the computable reals is not computable.  So it could
cause the compiler to loop during parsing. :)


Actually, that's one of the use cases ;)


A turing-complete type-checker isn't enough!  Our work is not  
complete until the parser is a universal machine as well!




Regards,
apfelmus



Rob Dockins

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



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


Re: Fractional/negative fixity?

2006-11-07 Thread Robert Dockins
On Tuesday 07 November 2006 17:32, Lennart Augustsson wrote:
 On Nov 7, 2006, at 11:47 , [EMAIL PROTECTED] wrote:
  Henning Thielemann wrote:
  On Tue, 7 Nov 2006, Simon Marlow wrote:
  I'd support fractional and negative fixity.  It's a simple change to
  make, but we also have to adopt
 
  http://hackage.haskell.org/cgi-bin/haskell-prime/trac.cgi/wiki/
  FixityResolution
 
  I've added the proposal to the end of that page.  In fact, the page
  already mentioned that we could generalise fixity levels, but it
  didn't
  mention fractional or negative values being allowed.
 
  Maybe that page could also mention earlier proposals and the
  solutions
  without precedence numbers. I prefer the non-numeric approach with
  rules
  like () binds more tightly than (), because it says what is
  intended
  and it allows to make things unrelated that are unrelated, e.g. infix
  operators from different libraries. Consequently a precedence
  relation to
  general infix operators like ($) and (.) had be defined in each
  library.
 
  I think that computable real fixity levels are useful, too. A further
  step to complex numbers is not advised because those cannot be
  ordered.

 But ordering of the computable reals is not computable.  So it could
 cause the compiler to loop during parsing. :)

   -- Lennart


Ha! Well, as long as we're being pedantic, surely we wouldn't need any set 
larger than the rationals (which does have a decidable ordering)?

Also, since I'm commenting anyway, I rather like the idea of specifying 
operator precedences via a partial order.  However, I also feel that there 
needs to be some work done to make sure there aren't gremlins hiding in the 
details.  Has anyone worked out the theory on this?  How does associating to 
the right vs left play into the picture?  How does it fit into the parsing 
technology?



-- 
Rob Dockins

Talk softly and drive a Sherman tank.
Laugh hard, it's a long way to the bank.
   -- TMBG
___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


[Haskell] [Announce] Yhc Bytecode library 0.3

2006-10-29 Thread Robert Dockins

[Please direct disccusion to the yhc list]

Fellow Haskellers,

I am pleased to announce the release of the Yhc Bytecode library,  
version 0.3.  The major differences from version 0.2 are:


* Updated to work with the current Yhc development branch as of  
2006-10-13
* API modified to fully handle the string table so that it is no  
longer exposed to the user

* Added support for the 'Ext' and 'Prim' object types
* Slightly improved some error messages

Source and Haddock documentation downloads are avaliable from:

http://www.eecs.tufts.edu/~rdocki01/yhc-bytecode.html

Direct access to the darcs repository from:
http://www.eecs.tufts.edu/~rdocki01/yhc-bytecode/



Rob Dockins

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

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


Re: [Haskell-cafe] Error building Edison 1.2.0.1

2006-10-18 Thread Robert Dockins


On Oct 17, 2006, at 1:46 PM, Gregory Wright wrote:



On Oct 17, 2006, at 1:07 PM, Robert Dockins wrote:



On Oct 17, 2006, at 12:55 PM, Gregory Wright wrote:



Hi Rob,

I've built Edison 1.2.0.1 using ghc-6.6.  (I'm testing the macports,
formerly darwinports, packages for the new 6.6 release.)

The build goes fine, but the ./Setup register fails claiming that  
the directory
/opt/local/lib/EdisonAPI-1.2/ghc-6.6/include does not exist.  I  
can make the
directory by hand, and the registration works.  I have an ugly  
workaround,
but I wanted to check with you that this is really a cabal bug.   
Installation

using ghc-6.4.2 on OS X/ppc worked just fine for me.

Best Wishes,
Greg



I'm not doing anything unusual with the cabal scripts (that I'm  
aware of!), so I expect this is a cabal or GHC bug.


BTW, could you run the test suite if you get a moment?  Every data  
point helps.





Hi Rob,

OK, it looks like cabal has gone slightly broken again. :-(



Any idea what the problem is?  Or why other people aren't yelling  
about it?  Is it only the register command that is broken?




Here's the test data:

OS X 10.4.8/ppc
PowerBook G4, 1.5 GHz, 1 GB ram
	ghc-6.6, cabal 1.1.6 as distributed with ghc-6.6, built using  
macports


test output:

Welcome to Darwin!
crossroads-able cd ~/Desktop/edison-1.2.0.1-source/test/
crossroads-able ./dist/build/testSuite/testSuite
Cases: 1728  Tried: 1728  Errors: 0  Failures: 0
crossroads-able



Excellent.  That's what I like to see.  Thanks!



Everything looks good but for the package registration.

I should add that I find the Edison package wonderfully easy
to work with.  It has really helped me out while writing simulation
of the custom communication system for a customer.  Many thanks
to you, Rob, and Chris Okasaki for this fine software!

Best Wishes,
Greg



Rob Dockins

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



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


Re: [Haskell-cafe] Newbie and working with IO Int and Int

2006-10-17 Thread Robert Dockins


On Oct 17, 2006, at 12:21 PM, Víctor A. Rodríguez wrote:


Hi all,

I'm really newbie to Haskell, and working on a program I'm trying  
to make

some testing.
I make some test on certain know values ( e.g. adding 10 to 15 must  
return
25) and some test on random values (eg. adding rnd1 to rnd2 must  
return

rnd1+rnd2).


Probably the best way to deal with this is to use the QuickCheck  
library.

http://www.cs.chalmers.se/~rjmh/QuickCheck/

It makes this sort of thing fairly painless, because you don't have  
to muck about with generating random data manually.



The problem that makes me mad is the random number generation. I  
can obtain
random numbers through module Random but all of them return IO Int  
values

(all I need are Ints) instead of Int.
I know that I can adjust my own functions to use IO Int instead of  
Int but
the call to certain functions must contain Int parameters, because  
these

ones can't be changed to accept IO Int (I read
http://haskell.org/hawiki/ThatAnnoyingIoType and know that can  
convert from

IO Int to Int :-P).

How can I deal with this problem ??


See: http://www.haskell.org/ghc/dist/current/docs/libraries/base/ 
System-Random.html


If you use 'getStdGen' or 'newStdGen' (which are in the IO monad),  
then you can later use the pure functions 'random', 'randomR' and  
friends.  Alternately, you can manually seed the PRNG with 'mkStdGen'  
and avoid the IO monad altogether.




Thanks in advance.
--
Víctor A. Rodríguez (http://www.bit-man.com.ar)
El bit Fantasma (Bit-Man)
Perl Mongers Capital Federal (http://cafe.pm.org/)
GNU/Linux User Group - FCEyN - UBA (http://glugcen.dc.uba.ar/)



Rob Dockins

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



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


Re: [Haskell-cafe] Error building Edison 1.2.0.1

2006-10-17 Thread Robert Dockins


On Oct 17, 2006, at 12:55 PM, Gregory Wright wrote:



Hi Rob,

I've built Edison 1.2.0.1 using ghc-6.6.  (I'm testing the macports,
formerly darwinports, packages for the new 6.6 release.)

The build goes fine, but the ./Setup register fails claiming that  
the directory
/opt/local/lib/EdisonAPI-1.2/ghc-6.6/include does not exist.  I can  
make the
directory by hand, and the registration works.  I have an ugly  
workaround,
but I wanted to check with you that this is really a cabal bug.   
Installation

using ghc-6.4.2 on OS X/ppc worked just fine for me.

Best Wishes,
Greg



I'm not doing anything unusual with the cabal scripts (that I'm aware  
of!), so I expect this is a cabal or GHC bug.


BTW, could you run the test suite if you get a moment?  Every data  
point helps.




Rob Dockins

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


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


Re: [Haskell-cafe] Newbie and working with IO Int and Int

2006-10-17 Thread Robert Dockins


On Oct 17, 2006, at 1:37 PM, Víctor A. Rodríguez wrote:


What's wrong with doing it this way?

-- ** UNTESTED CODE **

verifyAdd :: Int -gt; Int -gt; Int -gt; Bool
verifyAdd a b sum | a + b == sum = True
otherwise = False

testAddMundane :: Int -gt; Int -gt; Bool
testAddMundane a b = verifyAdd a b (a + b)

-- all the IO-dependent stuff is below this line --

testAddRandom :: IO Bool
testAddRandom = do a lt;- randomIO
b lt;- randomIO
return verifyAdd a b (a + b)


I discovered something worst yet :-P
Using the next code and calling verifyAdd or testAddMundane it says :

Program error: verifyAdd: ERROR

Instead calling testAddRandom only says :

:: IO Bool
(55 reductions, 92 cells)


This is due to the magic of lazy evaluation.  You never use the  
result of 'testAddRandom', so it's never evaluated, which means your  
call to 'error' is also never evaluated.


Type:

testAddRandom = print

on the command line and you should get the same error, because the  
call to 'print' demands the result of running testAddRandom.




 CODE STARTS HERE, AND IS TESTED -

import Random

verifyAdd :: Int - Int - Int - Bool
verifyAdd a b sum = error verifyAdd: ERROR

testAddMundane :: Int - Int - Bool
testAddMundane a b = verifyAdd a b (a + b)

-- all the IO-dependent stuff is below this line --

testAddRandom :: IO Bool
testAddRandom = do a - randomIO
b - randomIO
return ( verifyAdd a b (a+b) )

--
Víctor A. Rodríguez (http://www.bit-man.com.ar)
El bit Fantasma (Bit-Man)
Perl Mongers Capital Federal (http://cafe.pm.org/)
GNU/Linux User Group - FCEyN - UBA (http://glugcen.dc.uba.ar/)

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



Rob Dockins

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



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


Re: [Haskell-cafe] function result caching

2006-10-14 Thread Robert Dockins
On Saturday 14 October 2006 13:13, Ketil Malde wrote:
 Robert Dockins [EMAIL PROTECTED] writes:
  slowFunctionCacheList= [slowFunction (i) | i -[0..500]]
  and use slowFunctionCacheList !! i instead of slowFunction (i)
 
  Not much different in principle, but better in practice - you could
  use an array rather than a list.  O(1) lookups should make things (a
  lot) faster.
 
  Well, this is true only if the range of the domain function is small and
  fairly dense.

 I don't think so.

  With 500 elements, you're looking at allocating about 20Mb of
  memory

 On the other hand, the lists allocates the 20Mb of pointers, *and*
 another 20Mb of cons cells for the lists.

True, but only if you access deeply into the tail of the list.  If one access 
only the first several hundred elements, say, then you'll only allocate the 
space needed for those.

Of course, if you only want to access a small portion at the begining, then 
why create such a big list in the first place?  Moral: lists will lose this 
contest in almost all cases.

  to hold pointers to closures_ and then allocating and filling out 500
  closures, all before you get down to doing any real work!

 If I interpret you correctly, you want to make the array's contents
 strict?  Not a good idea when the domain is sparse, but on the other
 hand it would let you unbox the contents, which means you'd only need
 to store the actual values. For boolean values, I think GHC
 stores one bit per value, i.e. less than a MB for this range.

No, I didn't suggest that the elements be strict.  That would involve 
precomputing the entire table.  You _could_ do that if you anticipate a LOT 
of access to sufficient to outweigh the initial cost.  But that seems 
unlikely for a sparse domain, as you mentioned.

However, even non-strict arrays are created all at once (ie, they are strict 
in their _structure_), and the closures have to be allocated as the array is 
being created.  Creating a closure isn't terribly expensive, but creating 
500 closures might take awhile and cost a lot of memory if the closure 
has a large number of free variables (which depends on the function 
definition and the exact details of the lambda lifter).  Also, large arrays 
tend to play havoc with GHC's garbage collector; it has to scan all elements 
on every major GC, IIRC.  That alone may offset any advantages won.

In the end, the only way to be sure which method is best is to test it against 
your usage profile.  My guess is that the array method will have enough 
overhead that it will lose against a tree.  However I may be wrong, 
especially if the program will have a very long runtime and if a warm-up 
period is acceptable.

  Little-endian patricia trees [...]

 Yes, sure, if you can't afford a 20Mb index.  On the other hand,
 changing the function to use an array is a very small modification,
 and probably more than good enough in many cases.

I completely agree; it is good for many cases, and can be a very useful 
technique.  I just don't think it will be good for _this_ case (large, sparse 
domain where f(n) doesn't depend on all f(m) where m  n).  That probability 
is positively correlated with the size of the domain.  Again, the only way to 
really know is to implement and benchmark.  Thankfully, caching techniques 
are completely local and can be changed easily.

 -k

-- 
Rob Dockins

Talk softly and drive a Sherman tank.
Laugh hard, it's a long way to the bank.
   -- TMBG
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] function result caching

2006-10-13 Thread Robert Dockins
On Friday 13 October 2006 16:15, Ketil Malde wrote:
 Silviu Gheorghe [EMAIL PROTECTED] writes:
  slowFunctionCacheList= [slowFunction (i) | i -[0..500]]
  and use slowFunctionCacheList !! i instead of slowFunction (i)
 
  i am still curious about a better method (and a general one)

 Not much different in principle, but better in practice - you could
 use an array rather than a list.  O(1) lookups should make things (a
 lot) faster.

Well, this is true only if the range of the domain function is small and 
fairly dense.  He said it was large and sparsely populated.  

With 500 elements, you're looking at allocating about 20Mb of memory _just 
to hold pointers to closures_ and then allocating and filling out 500 
closures, all before you get down to doing any real work!  That's just not 
going to be very fast.  You're going to take a HUGE constant runtime and 
space penalty for that O(1) lookup.

Little-endian patricia trees are probably the right way to go here (which I 
think has been mentioned already).  You get O(log n) lookup and good behavior 
for a sparse and/or infinite domain because only the parts of the tree that 
are explored get unfolded.


 -k

-- 
Rob Dockins

Talk softly and drive a Sherman tank.
Laugh hard, it's a long way to the bank.
   -- TMBG
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] beginner's problem about lists

2006-10-11 Thread Robert Dockins


On Oct 11, 2006, at 10:14 AM, Malcolm Wallace wrote:


Matthias Fischmann [EMAIL PROTECTED] wrote:


No, your Fin type can also hold infinite values.


let q = FinCons 3 q in case q of FinCons i _ - i  ==  _|_

does that contradict, or did i just not understand what you are
saying?


That may be the result in ghc, but nhc98 gives the answer 3.

It is not entirely clear which implementation is correct.  The  
Language

Report has little enough to say about strict components of data
structures - a single paragraph in 4.2.1.  It defines them in terms of
the strict application operator ($!), thus ultimately in terms of seq,
and as far as I can see, nhc98 is perfectly compliant here.

The definition of seq is
seq _|_ b = _|_
seq  a  b = b, if a/= _|_

In the circular expression
let q = FinCons 3 q in q
it is clear that the second component of the FinCons constructor is  
not

_|_ (it has at least a FinCons constructor), and therefore it does not
matter what its full unfolding is.



Let's do some algebra.

data FinList a = FinCons a !(FinList a)


let q = FinCons 3 q in q
==
let q = ((\x1 x2 - (FinCons $ x1)) $! x2) 3 q in q   (translation  
from 4.2.1)

==
let q = (FinCons $ 3) $! q in q (beta)
==
let q = ($!) (($) FinCons 3) q in q (syntax)
==
let q = ($!) ((\f x - f x) FinCons 3) q in q   (unfold ($))
==
let q = ($!) (FinCons 3) q in q (beta)
==
let q = (\f x - seq x (f x)) (FinCons 3) q in q(unfold ($!))
==
let q = seq q (FinCons 3 q) in q(beta)


We have (from section 6.2):
   seq _|_ y = _|_
   seq x y = yiff x /= _|_


Now, here we have an interesting dilemma.  Suppose q is _|_, then:

let q = seq q (FinCons 3 q) in q
  ==
let q = _|_ in q(specification of  
seq)

  ==
_|_ (unfold let)


Instead suppose q /= _|_, then:

let q = seq q (FinCons 3 q) in q
  ==
let q = FinCons 3 q in q(specification of  
seq)

  ==
let q = FinCons 3 q in FinCons 3 q(unfold let)
  ==
FinCons 3 (let q = FinCons 3 q in q)   (float let)



It seems that both answers are valid, in that they conform to the  
specification.  Is 'seq' under-specified?  Using a straightforward  
operational interpretation, you will probably get the first answer, _| 
_, and this is what I have always assumed.  The second requires a  
sort of strange leap of faith to arrive at that answer (ie, assume  
'q' is non-bottom), and is less satisfying to me.  What do others think?





Regards,
Malcolm



Rob Dockins

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



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


Re: [Haskell-cafe] beginner's problem about lists

2006-10-11 Thread Robert Dockins


On Oct 11, 2006, at 11:14 AM, Ross Paterson wrote:


On Wed, Oct 11, 2006 at 11:04:49AM -0400, Robert Dockins wrote:

let q = seq q (FinCons 3 q) in q(beta)

We have (from section 6.2):
   seq _|_ y = _|_
   seq x y = yiff x /= _|_

Now, here we have an interesting dilemma.


The meaning of a recursive definition is the least fixed point of
the equation, in this case _|_.  Same as let x = x in x.



Ah... of course!  A simple explanation; I hoped there was one.   
It's nice that it coincides with what I wanted the answer to be. :-)




Rob Dockins

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



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


Re: [Haskell-cafe] a monad for secret information

2006-10-10 Thread Robert Dockins


On Oct 10, 2006, at 12:04 PM, Seth Gordon wrote:


data Secret a = Secret {password :: String, value :: a}

classify :: String - a - Secret a
classify = Secret

declassify :: String - Secret a - Maybe a
declassify guess (Secret pw v) | guess == pw = Just v
| otherwise = Nothing

Put that in a module, do not export the Secret data type, and you're
good to go. I'm unsure what a Monad is giving you


I was just curious if I could do that within a monad.

If the answer to my question is no, you can't, then I'll pick up the
shattered pieces of my life and move on.  :-)



I think you can.  Your original monad is just a little too  
simplistic.  Try something like this (untested):



import Control.Monad.State

type Password = String
type Secret s a = State (Password - Maybe s) a

classify :: Password - s - Secret s ()
classify pw s = put (\x - if x == pw then Just s else Nothing)

declassify :: Password - Secret s (Maybe s)
declassify pw = get = \f - return (f pw)

runSecret :: Secret s a - a
runSecret m = runState m (const Nothing)


Note how this relies on opaque functions to hide the secret.  This  
wouldn't work if Haskell had intensional observation of functions,  
although you could still use a newtype in that case.



Slightly related: I've sometimes wondered about a monadic API for  
cryptographic primitives.  With compiler support you could do nifty  
things like make sure to use non-swappable memory for encryption keys  
and use fancy special purpose hardware for cryptographic primitives,  
if available.  The API would give a nice way to ensure proper  
information hiding policy.  Has anything like this been done or studied?




Rob Dockins

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



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


Re: [Haskell-cafe] Error building Edison 1.2.0.1

2006-10-05 Thread Robert Dockins
On Thursday 05 October 2006 16:51, Lyle Kopnicky wrote:
 Robert Dockins wrote:
  On Wednesday 04 October 2006 16:16, Lyle Kopnicky wrote:
  Robert Dockins wrote:
  Whats the output of
 
  ghc-pkg -l
 
  ?
 
  [EMAIL PROTECTED]:~$ ghc-pkg -l
  /usr/local/lib/ghc-6.5.20060924/package.conf:
  Cabal-1.1.4, base-2.0, (ghc-6.5.20060924), haskell98-1.0,
  parsec-2.0, readline-1.0, regex-base-0.71, regex-compat-0.71,
  regex-posix-0.71, rts-1.0, stm-2.0, template-haskell-2.0, unix-1.0
  l
 
  Hummm.  Well, I confess that I'm confused.  Cabal 1.1.4 should work,
  because that's what I have on my machines; I've just tested it here.  The
  only thing I can think of is that the 'runhaskell' command is still bound
  to your old GHC, or to something else (Hugs maybe?).  If that's the case,
  you can edit the makefile and set the 'RUNHS' variable in the first line
  to the full path to your 6.5 runghc.  Or you can edit the .cabal files as
  suggested above.

 I don't have hugs installed, and I've uninstalled ghc 6.4.1, so it can
 only be running 6.5.

 I've pasted the error in again here for reference:
  [EMAIL PROTECTED]:~/devel/edison-1.2.0.1-source$ sudo make system
  Password:
  cd edison-api  \
runhaskell Setup.hs configure  \
runhaskell Setup.hs build  \
runhaskell Setup.hs install
  Configuring EdisonAPI-1.2...
  configure: Dependency base=1.0: using base-2.0
  configure: Dependency haskell98=1.0: using haskell98-1.0
  Setup.hs: cannot satisfy dependency mtl=1.0
  make: *** [api-system] Error 1
  [EMAIL PROTECTED]:~/devel/edison-1.2.0.1-source$

 Do you know what mtl is?

mtl is the Monad Transformer Library.  It's a part of the standard libraries 
in 6.4.x.  There's been a good deal of chatter recently about reducing the 
set of libraries the GHC ships with; it may be that mtl is on that list.  I 
haven't really been following, so I'm not sure.

 Maybe there's something broken in this GHC 
 snapshot. I've already noticed Template Haskell seems to be broken in it.

Possible.  I also notice that QuickCheck isn't in your list of installed 
packages.  You'll need that to compile edison-core.



 - Lyle

-- 
Rob Dockins

Talk softly and drive a Sherman tank.
Laugh hard, it's a long way to the bank.
   -- TMBG
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Error building Edison 1.2.0.1

2006-10-04 Thread Robert Dockins
On Tuesday 03 October 2006 22:58, Lyle Kopnicky wrote:
 Robert Dockins wrote:
  On Tuesday 03 October 2006 22:00, Lyle Kopnicky wrote:
  Hi folks,
 
  I tried to build edison-1.2.0.1-sources with the command 'make system'
  but got:
 
  *** Exception: Line 10: Unknown field 'hs-source-dirs'
 
  I am using GHC 6.4.1. Any idea how to fix this?
 
  You are probably using an older version of Cabal.  You can either upgrade
  Cabal or, from the Edison README*:
 
 
  This version of edison builds correctly with Cabal version 1.1.4,
  which is shipped with GHC 6.4.2.  To build on earlier versions,
  it should suffice to:
 
  s/UndecidableInstances/AllowUndecidableInstances/
  s/Hs-Source-Dirs:/Hs-Source-Dir:/
 
  in the .cabal files.
 
 
 
  The 'hs-source-dir' cabal directive was depreciated in 1.1.4, but perhaps
  I should have waited a bit longer to change it.  OTOH, there isn't any
  good way to deal with the change in the undecidable instances flag, since
  it was outright changed.  G. *grumble* incompatible changes in
  minor releases *grumble*.
 
 
  (*) Further, g... in the above, I've fixed several embarrasing typos
  in the text of the README.

 Oh, OK, thanks! Well, now I'm running GHC 6.5.20060924, and getting the
 error mentioned in my previous message.

Whats the output of

ghc-pkg -l

?


 - Lyle

-- 
Rob Dockins

Talk softly and drive a Sherman tank.
Laugh hard, it's a long way to the bank.
   -- TMBG
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Error building Edison 1.2.0.1

2006-10-04 Thread Robert Dockins
On Wednesday 04 October 2006 16:16, Lyle Kopnicky wrote:
 Robert Dockins wrote:
  On Tuesday 03 October 2006 22:58, Lyle Kopnicky wrote:
  Robert Dockins wrote:
  On Tuesday 03 October 2006 22:00, Lyle Kopnicky wrote:
  Hi folks,
 
  I tried to build edison-1.2.0.1-sources with the command 'make system'
  but got:
 
  *** Exception: Line 10: Unknown field 'hs-source-dirs'
 
  I am using GHC 6.4.1. Any idea how to fix this?
 
  You are probably using an older version of Cabal.  You can either
  upgrade Cabal or, from the Edison README*:
 
 
  This version of edison builds correctly with Cabal version 1.1.4,
  which is shipped with GHC 6.4.2.  To build on earlier versions,
  it should suffice to:
 
  s/UndecidableInstances/AllowUndecidableInstances/
  s/Hs-Source-Dirs:/Hs-Source-Dir:/
 
  in the .cabal files.
 
 
 
  The 'hs-source-dir' cabal directive was depreciated in 1.1.4, but
  perhaps I should have waited a bit longer to change it.  OTOH, there
  isn't any good way to deal with the change in the undecidable instances
  flag, since it was outright changed.  G. *grumble* incompatible
  changes in minor releases *grumble*.
 
 
  (*) Further, g... in the above, I've fixed several embarrasing
  typos in the text of the README.
 
  Oh, OK, thanks! Well, now I'm running GHC 6.5.20060924, and getting the
  error mentioned in my previous message.
 
  Whats the output of
 
  ghc-pkg -l
 
  ?

 [EMAIL PROTECTED]:~$ ghc-pkg -l
 /usr/local/lib/ghc-6.5.20060924/package.conf:
 Cabal-1.1.4, base-2.0, (ghc-6.5.20060924), haskell98-1.0,
 parsec-2.0, readline-1.0, regex-base-0.71, regex-compat-0.71,
 regex-posix-0.71, rts-1.0, stm-2.0, template-haskell-2.0, unix-1.0
 l

Hummm.  Well, I confess that I'm confused.  Cabal 1.1.4 should work, because 
that's what I have on my machines; I've just tested it here.  The only thing 
I can think of is that the 'runhaskell' command is still bound to your old 
GHC, or to something else (Hugs maybe?).  If that's the case, you can edit 
the makefile and set the 'RUNHS' variable in the first line to the full path 
to your 6.5 runghc.  Or you can edit the .cabal files as suggested above.


-- 
Rob Dockins

Talk softly and drive a Sherman tank.
Laugh hard, it's a long way to the bank.
   -- TMBG
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Error building Edison 1.2.0.1

2006-10-03 Thread Robert Dockins
On Tuesday 03 October 2006 22:00, Lyle Kopnicky wrote:
 Hi folks,

 I tried to build edison-1.2.0.1-sources with the command 'make system'
 but got:

 *** Exception: Line 10: Unknown field 'hs-source-dirs'

 I am using GHC 6.4.1. Any idea how to fix this?

You are probably using an older version of Cabal.  You can either upgrade 
Cabal or, from the Edison README*:


This version of edison builds correctly with Cabal version 1.1.4,
which is shipped with GHC 6.4.2.  To build on earlier versions,
it should suffice to:

s/UndecidableInstances/AllowUndecidableInstances/
s/Hs-Source-Dirs:/Hs-Source-Dir:/

in the .cabal files.



The 'hs-source-dir' cabal directive was depreciated in 1.1.4, but perhaps I 
should have waited a bit longer to change it.  OTOH, there isn't any good way 
to deal with the change in the undecidable instances flag, since it was 
outright changed.  G. *grumble* incompatible changes in minor 
releases *grumble*.


(*) Further, g... in the above, I've fixed several embarrasing typos in 
the text of the README.

 Thanks,
 Lyle

-- 
Rob Dockins

Talk softly and drive a Sherman tank.
Laugh hard, it's a long way to the bank.
   -- TMBG
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Is Haskell a 5GL?

2006-09-29 Thread Robert Dockins

On Sep 28, 2006, at 8:47 PM, David Curran wrote:


Sorry if this comes across as the rant it is. If you are interested in
doing useful stuff rather then navel gazing please stop here.

Where are compute languages going?
I think multi core, distributed, fault tolerant.
So you would end up with a computer of the sort envisioned by Hillis
in the 80s with his data parallel programs. The only language that
seems even close to this model is Erlang. What am I missing about the
ability of Haskell to distribute across processors or a network?

Say instead of fault tolerant it is fault avoiding.
Can proving programs correct (with Haskell) really reduce our  
workload?

http://www.seas.upenn.edu/~sweirich/wmm/03-benton.pdf


I read that paper as saying formal methods have an extremely steep  
learning curve and large initial investment, but that the learning  
and initial investment pay off over time.  The author found that,  
even in the short time he worked with it, formal methods saved time  
when he needed to modify his definitions (third paragraph in the  
second column).  As with many automation tasks, the payoff comes with  
repeated identical or similar iterations.  Furthermore, his acquired  
knowledge transferred well to an unrelated project.  I can personally  
vouch for many of his experiences, having worked some with Coq myself.



Finally is Haskell a language for programming or a mental gymnasium
that might be the proving ground for concepts in the next popular
language? To quote from a post on the topic Old functional
programming ideas  on programming.reddit.com


I don't know how much you agree with this quote, but for the purposes  
of discussion I'll assume that you have expressed these views  
personally.  You did, after all, preface your message by saying it  
was a rant so I'm going to assume you're prepared for the flames. ;-)



Church-Turing equivalence tells us that all models of recursive
computing have the same formal power. But it tells us nothing about
which models are the most effective way for humans to understand and
express definitions of functions. For some reason I'd expect
researchers in programming languages to have a lot of opinions on this
subject. But they don't seem to talk about it much.


I think the Haskell community is doing better than many in this  
regard.  There is a concurrent thread on haskell-prime occurring  
_right now_ about whether pattern guards should be in Haskell'.  The  
primary point of disagreement is about whether pattern guards are a  
more effective way for humans to understand and express definitions  
of functions or not!  The ages-old disagreement about top-level state  
is similar, if more heated.  Similar for (n+k) patterns, and a host  
of other issues.  The endless discussions about monads often revolve  
around the goal of achieving new and better ways to express  
complicated function definitions.


I think this is because a fundamental value of the Haskell community  
is flexibility of the language.  Many languages are presented to the  
programmer as a complete package, which doesn't encourage them to  
consider the various possible design decisions that went into  
creating that language.  With Haskell, new users are often quickly  
confronted with various different ways of expressing their goals and  
with extensions they can enable (or not) and are forced to consider  
how best to express their program.  I think this is more good than it  
is bad.



Instead, a cynical and mean-spirited person might come to the
conclusion that PL researchers (such as Wadler) are actually just
mathematicians,


You seem to say this like its a bad thing; I completely disagree.  I  
don't think of myself as mean-spirited, and I have no problems  
calling, eg, Wadler a mathematician.  Just as I would call Church and  
Turing and Kleene and Goedel and Milner (etc, etc, etc)  
mathematicians.  If someone were ever to call _me_ a mathematician, I  
would consider it an honor.  Furthermore, if anyone attempted to  
belittle these distinguished persons or their accomplishments by  
calling them just mathematicians, I would begin to question his or  
her qualifications to have an opinion on the subject worthy of  
consideration.


The field mathematics has a long and glorious history of helping  
people to solve real problems.  I don't understand this undercurrent  
of antagonism that some people in our field have towards it.  Let's  
be honest: developing correct programs that perform non-trivial tasks  
and reasoning about them is HARD.  The techniques of mathematics and  
its sister discipline formal logic can help us with these tasks.  I  
find it a little strange that this position even requires a defense.   
All of the other scientific and engineering disciplines embrace the  
mathematics that help them do their work.  I don't believe there are  
very many physicists who would call Newton a mathematician and intend  
it to be a derogatory term.


I 

Re: [Haskell-cafe] Optimizing a title matcher

2006-09-26 Thread Robert Dockins
On Tuesday 26 September 2006 16:44, Lyle Kopnicky wrote:
 Hi folks,

 I'm competing in a contest at work, and we're allowed to use whatever
 language we want. I decided this was my chance to prove to people that
 Haskell was up to the challenge. Unfortunately, I ran into performance
 problems. Since the contest ends this Friday, I've decided to switch to
 C++ (gasp!). But if any of you have advice on how to speed up this code,
 it could help me advocate Haskell in the future.

 It's supposed to match movie titles from an imported database to a
 reference database. The version I've sent doesn't do anything very smart
 - it's just doing literal title matches. The first argument to the
 program is the filename of the table to be imported, and the second is
 the filename of the reference table. The first line of each table is a
 pipe-separated list of field names; the rest of the lines are records,
 each a pipe-separated list of values.

 The import files each have 3,000 records, and the reference table has
 137,986 records.

 Building the hash tables out of the files is quick - it just takes a few
 seconds. But doing the matching of title_id in one table to title_id in
 the other, in a nested loop between both tables, takes way too long.
 It's matching two import titles (against each of the reference titles)
 per second. It needs to do at least 20 per second to qualify for the
 contest, and it's not doing anything fancy yet.

Humm... well, double nested loops seems like the wrong approach.  Also, if you 
are using GHC, it's hashtable implementation has farily well-known 
performance problems. If all you care about is exact matching, then the 
operation is essentially a finite map intersection (if I've understood what 
you are trying to do).

This is just a guess, but I suspect you will probably get much better 
performance (and better-looking code!) by just using Data.Map.intersection
 
http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Map.html#v%3Aintersection

Alternately, there is the ternary trie implementation from Edison 
(http://www.eecs.tufts.edu/~rdocki01) that may also work for you.

If you need to do prefix matching, then a trie is the way to go.  You can 
probably code up a nice prefix-intersection operation using tries that should 
go pretty fast.

If you have some other metric other than prefix in mind for partial matches, 
then things probably get a lot more complicated.  You're probably looking at 
calculating minimum distances in some feature-space, which calls for pretty 
sophisticated algorithms if you need good performance.

 I tried various improvements to speed it up. One was to specifically
 use ByteString, eliminating the AbsString class. Didn't make a
 difference. Another was to use arrays instead of lists to store each
 record, and precompute the indices of each of the fields within those
 records. I also iterated over a list of keys instead of the list of
 Maps, and only converted each record to a Map one at a time, hoping they
 would be disposed of sooner. Instead of speeding up the program, this
 slowed it down by a factor of 20!

 I've profiled it, and I can't make much out of that. It seemed to be
 spending 25% of its time doing scoring, and I though the problem must be
 due to laziness, but I'm not sure.

 So if anyone has any ideas how to speed this up by a factor of at least
 10 times, it would be really appreciated! Even the Ruby solutions are
 doing that, which is embarrassing.

 Thanks,
 Lyle

-- 
Rob Dockins

Talk softly and drive a Sherman tank.
Laugh hard, it's a long way to the bank.
   -- TMBG
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Optimization problem

2006-09-19 Thread Robert Dockins


On Sep 19, 2006, at 8:52 AM, Conor McBride wrote:


Hi folks

[EMAIL PROTECTED] wrote:
Btw, why are there no irrefutable patterns for GADTs? I mean, such  
a sin

should be shame for a non-strict language...




Just imagine

 data Eq a b where Refl :: Eq a a

 coerce :: Eq a b - a - b
 coerce ~Refl a = b



I think you mean:

 coerce ~Refl x = x



coerce undefined True :: String

Bang you're dead. Or rather... Twiddle you're dead.

Moral: in a non-total language, if you're using indexing to act as  
evidence for something, you need to be strict about checking the  
evidence before you act on it, or you will be vulnerable to the  
blandishments of the most appalling liars.


As Randy Pollack used to say to us when we were children, the best  
thing about working in a strongly normalizing language is not  
having to normalize things.


All the best

Conor



Rob Dockins

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



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


Re: [Haskell] How to define Y combinator in Haskell

2006-09-15 Thread Robert Dockins
On Friday 15 September 2006 12:45, David House wrote:
 On 15/09/06, Haihua Lin [EMAIL PROTECTED] wrote:
  Is there a way to define it in Haskell?

 Note that the function 'fix' (find the fixpoint of a function) already
 exists in Haskell, and is equivalent to the Y combinator.

 It's interesting that most (all?) fixed-point combinators don't
 typecheck. The Y combinator, and by extension recursion in general,
 has to be added as a constant to the language.

This actually isn't true.  You can define a direct fixed point combinator 
without relying on nominal recursion in Haskell, but it requires you to 
define a helper newtype.  

Don't run this in GHC because it will diverge.  Hugs works, however.



newtype Mu a = Roll (Mu a - (a - a))
unroll (Roll x) = x

fix :: (a - a) - a - a
fix = \f -   (\x z - f ((unroll x) x z))
(Roll (\x z - f ((unroll x) x z)))

facF :: (Int - Int) - Int - Int
facF f x
  | x = 0= 1
  | otherwise = x * (f (x-1))

fac :: Int - Int
fac = fix facF undefined

main = print $ fac 5





Rob Dockins

Talk softly and drive a Sherman tank.
Laugh hard, it's a long way to the bank.
   -- TMBG
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] How to define Y combinator in Haskell

2006-09-15 Thread Robert Dockins
On Friday 15 September 2006 14:48, Michael Shulman wrote:
 On 9/15/06, Robert Dockins [EMAIL PROTECTED] wrote:
  You can define a direct fixed point combinator
  without relying on nominal recursion in Haskell, but it requires you to
  define a helper newtype.

 That's really nifty!  I'd been wondering whether you could do this
 too.  Is there a reason for the extra `z' parameter?

It made the typing work out ;-)  It can probably be eliminated, but I haven't 
bothered to figure out how.  I originally wrote it as a mental exercise and 
stopped once I got it to work.

  Don't run this in GHC because it will diverge.  Hugs works, however.

 According to

 http://www.haskell.org/pipermail/glasgow-haskell-bugs/2001-August/001717.ht
ml

 this is due to a bug in the GHC inliner that probably won't be fixed.
 However, experimentation indicates you can work around the bug using
 the NOINLINE pragma:


 newtype Mu a = Roll { unroll :: Mu a - a }

 fix :: (a - a) - a
 fix f = doink (Roll doink)
 where {-# NOINLINE doink #-}
   doink x = f ((unroll x) x)


 Mike

-- 
Rob Dockins

Talk softly and drive a Sherman tank.
Laugh hard, it's a long way to the bank.
   -- TMBG
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] xml-rpc in hugs

2006-09-08 Thread Robert Dockins


On Sep 8, 2006, at 6:30 AM, David Tolpin wrote:


Hi,

I'm trying to use xmlrpc module with hugs. The problems are not  
really related to this particulare module, so the question is here.



A module generated from the DTD for XML-RPC by HaXml contains  
import in the following form:


import Prelude (all, maybe, (++))

or something like that to avoid name conflicts with types of the  
same name defined in the module. In Hugs it leads to (:) not being  
imported into the module. Is there a way to import just (:) from  
the Prelude?


This one is tricky due to the fact that (:) is very special.  I think  
various Haskell implementations differ on exactly how this is  
handled.  I don't know enough about Hugs to say for sure.



Is there a way to import all but some symbols from some module?


Yes.  You want the 'hiding' keyword, eg,

import Prelude hiding (foo, bar, baz)


Is (:) a data constructor?


Yes.


David




Rob Dockins

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



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


Re: [Haskell-cafe] Monad laws

2006-09-07 Thread Robert Dockins


On Sep 7, 2006, at 9:04 AM, Lennart Augustsson wrote:


Brian,

Are you really sure Haskell compilers do that optimization?
I would regard a compiler that does optimizations that are  
justified by laws that the compiler cannot check as broken.


What, like list fusion?

;-)

Although, more seriously, there are a number of monads in the  
standard libs that don't follow the monad laws (including IO http:// 
article.gmane.org/gmane.comp.lang.haskell.general/5273  !!).


I can't imagine that any haskell compilers rely on these laws to do  
program transformations.




-- Lennart

On Sep 7, 2006, at 08:50 , Brian Hulley wrote:


Deokhwan Kim wrote:

What is the practical meaning of monad laws?

(M, return, =) is not qualified as a category-theoretical  
monad, if

the following laws are not satisfied:

 1. (return x) = f == f x
 2. m = return == m
 3. (m = f) = g == m  (\x - f x = g)

But what practical problems can unsatisfying them cause? In other
words, I wonder if declaring a instance of the Monad class but not
checking it for monad laws may cause any problems, except for not
being qualified as a theoretical monad?


Afaiu the monad laws are needed so the compiler can do various  
optimizations, especially in regard to the do notation. Consider:


   g c = do
   if c
   then p
   else return ()
   q

Intuitively, the else branch of the if statement does nothing  
interesting, but we need to put something there because we can't  
just leave the branch empty, hence the use of (return ()), but  
thankfully, because of the monad laws, the compiler can apply  
transformations to get rid of it when it desugars the do notation.


The above is equivalent to:

   g c = (if c then p else return ()) = (\_ - q)

which could be re-written as:

   g c = if c then (p = (\_ - q)) else (return () = (\_ - q))

which can be optimized using monad law 1) to:

   g c = if c then (p = (\_ - q)) else (\_ - q) ()

which can further be optimized to:

   g c = if c then (p = (\_ - q)) else q

so when the condition (c) is False we don't waste time doing the  
(return ()) action, but go straight to (q).


However if your monad didn't satisfy the laws, the compiler would  
still assume that it did thus leading to a flawed optimization  
ie the compiler would throw your program away and substitute it  
for a different, unrelated, program...


Regards, Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

http://www.metamilk.com




Rob Dockins

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



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


GHC non-termination

2006-09-05 Thread Robert Dockins

Hello all,

I've discovered that GHC doesn't deal very well with the following  
program.  It appears to diverge when running the following program  
with 'runghc'.  The main compiler can also be persuaded to diverge in  
a similar fashion.  Hugs exhibits correct behavior, ie, it prints  
hello.


This is with GHC 6.4.2.  I've tested on linux x86 and PPC OS X.



newtype Mu a = Roll { unroll :: Mu a - a }

omega :: a
omega = (\x - (unroll x) x) (Roll (\x - (unroll x) x))

main = putStrLn hello



Rob Dockins

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



___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: GHC non-termination

2006-09-05 Thread Robert Dockins

Ah.  My apologies for bringing up such a well-worn issue, then.


On Sep 5, 2006, at 3:38 PM, Simon Peyton-Jones wrote:


You and many others --- but the example is always the same!
http://www.haskell.org/ghc/docs/latest/html/users_guide/ 
bugs.html#bugs-g

hc

Simon

| -Original Message-
| From: [EMAIL PROTECTED]
[mailto:glasgow-haskell-users-
| [EMAIL PROTECTED] On Behalf Of Robert Dockins
| Sent: 05 September 2006 20:48
| To: glasgow-haskell-users@haskell.org
| Subject: GHC non-termination
|
| Hello all,
|
| I've discovered that GHC doesn't deal very well with the following
| program.  It appears to diverge when running the following program
| with 'runghc'.  The main compiler can also be persuaded to  
diverge in

| a similar fashion.  Hugs exhibits correct behavior, ie, it prints
| hello.
|
| This is with GHC 6.4.2.  I've tested on linux x86 and PPC OS X.
|
|
|
| newtype Mu a = Roll { unroll :: Mu a - a }
|
| omega :: a
| omega = (\x - (unroll x) x) (Roll (\x - (unroll x) x))
|
| main = putStrLn hello
|
|
|
| Rob Dockins
|
| Speak softly and drive a Sherman tank.
| Laugh hard; it's a long way to the bank.
|-- TMBG
|
|
|
| ___
| Glasgow-haskell-users mailing list
| Glasgow-haskell-users@haskell.org
| http://www.haskell.org/mailman/listinfo/glasgow-haskell-users




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



___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: [Haskell-cafe] Exercise in point free-style

2006-09-01 Thread Robert Dockins
On Friday 01 September 2006 11:44, Neil Mitchell wrote:
 Hi

  func2 f g l = filter f (map g l)
  is
  func2p f g = (filter f) . (map g)

 func2 = (. map) . (.) . filter

 Again, how anyone can come up with a solution like this, is entirely
 beyond me...

To answer part of the OP's question, it's always possible to rewrite a lambda 
term using point-free style (using a surprisingly small set of basic 
combinators).  The price you pay is that the new term is often quite a bit 
larger than the old term.  Rewriting complicated lambda terms as point-free 
terms is often of, em, dubious value.  OTOH, it can be interesting for 
understanding arrows, which are a lot like monads in points-free style (from 
what little experience I have with them).

BTW, the process of rewriting can be entirely automated.  I assume the 
lambdabot is using one of the well-known algorithms, probably tweaked a bit.

Goolge combinatory logic or Turner's combinators if you're curious.


 Thanks

 Neil


-- 
Rob Dockins

Talk softly and drive a Sherman tank.
Laugh hard, it's a long way to the bank.
   -- TMBG
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] getContents and lazy evaluation

2006-09-01 Thread Robert Dockins
On Friday 01 September 2006 15:19, Tamas K Papp wrote:
 Hi,

 I am newbie, reading the Gentle Introduction.  Chapter 7
 (Input/Output) says

   Pragmatically, it may seem that getContents must immediately read an
   entire file or channel, resulting in poor space and time performance
   under certain conditions. However, this is not the case. The key
   point is that getContents returns a lazy (i.e. non-strict) list of
   characters (recall that strings are just lists of characters in
   Haskell), whose elements are read by demand just like any other
   list. An implementation can be expected to implement this
   demand-driven behavior by reading one character at a time from the
   file as they are required by the computation.

 So what happens if I do

 contents - getContents handle
 putStr (take 5 contents) -- assume that the implementation
-- only reads a few chars
 -- delete the file in some way
 putStr (take 500 contents) -- but the file is not there now

 If an IO function is lazy, doesn't that break sequentiality?  Sorry if
 the question is stupid.

This is not a stupid question at all, and it highlights the main problem with 
lazy IO.  The solution is, in essence don't do that, because Bad Things will 
happen.  It's pretty unsatisfactory, but there it is.  For this reason, lazy 
IO is widely regarded as somewhat dangerous (or even as an outright 
misfeature, by a few).

If you are going to be doing simple pipe-style IO (ie, read some data 
sequentially, manipulate it, spit out the output),  lazy IO is very 
convenient, and it makes putting together quick scripts very easy.  However, 
if you're doing something more advanced, you'd probably do best to stay away 
from lazy IO.

Welcome to Haskell, BTW  :-)

 Thanks,

 Tamas

-- 
Rob Dockins

Talk softly and drive a Sherman tank.
Laugh hard, it's a long way to the bank.
   -- TMBG
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] getContents and lazy evaluation

2006-09-01 Thread Robert Dockins
On Friday 01 September 2006 16:46, Duncan Coutts wrote:
 On Fri, 2006-09-01 at 16:28 -0400, Robert Dockins wrote:
  On Friday 01 September 2006 15:19, Tamas K Papp wrote:
   Hi,
  
   I am newbie, reading the Gentle Introduction.  Chapter 7
   (Input/Output) says
  
 Pragmatically, it may seem that getContents must immediately read an
 entire file or channel, resulting in poor space and time performance
 under certain conditions. However, this is not the case. The key
 point is that getContents returns a lazy (i.e. non-strict) list of
 characters (recall that strings are just lists of characters in
 Haskell), whose elements are read by demand just like any other
 list. An implementation can be expected to implement this
 demand-driven behavior by reading one character at a time from the
 file as they are required by the computation.
  
   So what happens if I do
  
   contents - getContents handle
   putStr (take 5 contents) -- assume that the implementation
  -- only reads a few chars
   -- delete the file in some way
   putStr (take 500 contents) -- but the file is not there now
  
   If an IO function is lazy, doesn't that break sequentiality?  Sorry if
   the question is stupid.
 
  This is not a stupid question at all, and it highlights the main problem
  with lazy IO.  The solution is, in essence don't do that, because Bad
  Things will happen.  It's pretty unsatisfactory, but there it is.  For
  this reason, lazy IO is widely regarded as somewhat dangerous (or even as
  an outright misfeature, by a few).
 
  If you are going to be doing simple pipe-style IO (ie, read some data
  sequentially, manipulate it, spit out the output),  lazy IO is very
  convenient, and it makes putting together quick scripts very easy. 
  However, if you're doing something more advanced, you'd probably do best
  to stay away from lazy IO.

 Since working on Data.ByteString.Lazy I'm now even more of a pro-lazy-IO
 zealot than I was before ;-)

 In practise I expect that most programs that deal with file IO strictly
 do not handle the file disappearing under them very well either.

That's probably true, except for especially robust applications where such a 
thing is a regular (or at least expected) event.

 At best 
 the probably throw an exception and let something else clean up. The
 same can be done with lazy I, though it requires using imprecise
 exceptions which some people grumble about. So I would contend that lazy
 IO is actually applicable in rather a wider range of circumstances than
 you might. :-)

Perhaps I should be more clear.  When I said advanced above I meant any use 
whereby you treat a file as random access, read/write storage, or do any kind 
of directory manipulation (including deleting and or renaming files).  Lazy 
I/O (as it currently stands) doesn't play very nice with those use cases.

I agree generally with the idea that lazy I/O is good.  The problem is that it 
is a leaky abstraction; details are exposed to the user that should ideally 
be completely hidden.  Unfortunately, the leaks aren't likely to get plugged 
without pretty tight operating system support, which I suspect won't be 
happening anytime soon.

 Note also, that with lazy IO we can write really short programs that are
 blindingly quick. Lazy IO allows us to save a copy through the Handle
 buffer.

 BTW in the above case the bad thing that will happen is that contents
 will be truncated. As I said, I think it's better to throw an exception,
 which is what Data.ByteString.Lazy.hGetContents does.

Well, AFAIK, the behavior is officially undefined, which is my real beef.  I 
agree that it _should_ throw an exception.

 Duncan

-- 
Rob Dockins

Talk softly and drive a Sherman tank.
Laugh hard, it's a long way to the bank.
   -- TMBG
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] getContents and lazy evaluation

2006-09-01 Thread Robert Dockins
On Friday 01 September 2006 18:01, Donn Cave wrote:
 On Fri, 1 Sep 2006, Robert Dockins wrote:
  On Friday 01 September 2006 16:46, Duncan Coutts wrote:

 ...

  Note also, that with lazy IO we can write really short programs that are
  blindingly quick. Lazy IO allows us to save a copy through the Handle
  buffer.

 (Never understood why some people think it would be such a good thing
 to be blinded, but as long as it's you and not me ... )

  BTW in the above case the bad thing that will happen is that contents
  will be truncated. As I said, I think it's better to throw an exception,
  which is what Data.ByteString.Lazy.hGetContents does.
 
  Well, AFAIK, the behavior is officially undefined, which is my real beef.
   I agree that it _should_ throw an exception.

 Is this about Microsoft Windows?  On UNIX, I would expect deletion of
 a file to have no effect on I/O of any kind on that file.  I thought
 the problems with hGetContents more commonly involve operations on
 the file handle, e.g., hClose.

Ahh... I think you're right.

However, this just illustrates the problem.  The point is that the answer the 
question what happens when I do odd thing involving lazy I/O is it 
depends.  And to the obvious followup question what does it depend on? the 
answer is well it's complicated.

   Donn Cave, [EMAIL PROTECTED]

-- 
Rob Dockins

Talk softly and drive a Sherman tank.
Laugh hard, it's a long way to the bank.
   -- TMBG
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: A free monad theorem?

2006-08-31 Thread Robert Dockins
 So getting the value out of the monad is not a pure function (extract ::
 Monad m = m a - a). I think I stated that, already, in my previous post.
 I'd even say that the monadic values alone can be completely meaningless.
 They often have a meaning only relative to some environment, thus are
 (usually) _effectful_ computations. But we already knew that, didn't we?

It may help to remember that, in the mathematical context where monads where 
born (AKA category theory), a monad is generally defined as a functor with a 
join and a unit (satisfying some laws that I would have to look up).  The 
unit should be familiar (it's spelled 'return' in haskell), but join may not 
be.  Its type is

join :: Monad m = m (m a) - m a

which is a lot like extract, except with one more monad layer wrapped around 
it.  IIRC the relevant identity here is:

x = f === join (fmap f x)

and with f specialzed to id:

join (fmap id x) === x = id
join x   === x = id

I'm not sure why (=) is taken as basic in Haskell.  At any rate, my point is 
that I think your questions might be better framed in terms of the behavior 
of 'fmap'.

 The real question (the one that bugs me, anyway) is if one can give a
 precise meaning to the informal argument that if the definition of bind is
 to be non-trivial then its second argument must be applied to some
 non-trivial value at one point (but not, of course, in all cases, nor
 necessarily only once), and that this implies that the computation
 represented by the first argument must somehow be 'run' (in some
 environment) in order to produce such a value. -- And, of course, whether
 this is actually true in the first place. Would you say that your examples
 above are counter-examples to this statement (imprecise as it is,
 unfortunately)?

 Ben




-- 
Rob Dockins

Talk softly and drive a Sherman tank.
Laugh hard, it's a long way to the bank.
   -- TMBG
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] a novice Alex question

2006-08-25 Thread Robert Dockins


On Aug 25, 2006, at 6:27 AM, Xiong Yingfei wrote:


Hi,

I am trying out Alex. I copied the calculator specification file  
from Alex's official document and changed the wrapper type from  
basic to monad. However, after I generated the .hs file from  
the lexical specification and compiled the .hs file, I got the  
message Variable not in scope: `alexEOF'. I cannot find  
explanation about this 'alexEOF' function in the document. Can any  
body be kindly enough to tell me what this function is? Should I  
write it myself or not? My lexical code is listed as the below.  
Thanks a lot.


You should provide alexEOF.  The idea is that it is a special token  
representing the end of input.  This is necessary because the monad  
wrapper doesn't deliver a list of tokens like the basic wrapper, so  
it needs some way to signal the end of input.  The easiest thing to  
do is add a constructor to your token datatype, and then just set  
alexEOF to that constructor:


data Token =
   
   | EOFToken


alexEOF = EOFToken





{
module Lex where

}

%wrapper monad

$digit = 0-9   -- digits
$alpha = [a-zA-Z]  -- alphabetic characters

tokens :-

  $white+;
  --.*;
  let { \s - Let }
  in { \s - In }
  $digit+{ \s - Int (read s) }
  [\=\+\-\*\/\(\)]   { \s - Sym (head s) }
  $alpha [$alpha $digit \_ \']*  { \s - Var s }

{
-- Each action has type :: String - Token

-- The token type:
data Token =
 Let   |
 In|
 Sym Char |
 Var String |
 Int Int
 deriving (Eq,Show)
}

--
Xiong, Yingfei (熊英飞)
Ph.D. Student
Institute of Software
School of Electronics Engineering and Computer Science
Peking University
Beijing, 100871, PRC.
Web: http:// 
xiong.yingfei.googlepages.com_ 
__



Rob Dockins

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



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


Re: [Haskell-cafe] Derived Read instance for types with infix constructors (ghc 6.4.1)

2006-08-25 Thread Robert Dockins


On Aug 25, 2006, at 6:50 PM, Misha Aizatulin wrote:


hi,

  the Haskell Report 10.4 says that

The result of show is readable by read if all component types are  
readable


  however if I define a type like

data T = A | T `And` T deriving (Read, Show)

  then

*Main show $ A `And` A
A And A
*Main (read A And A) :: T
*** Exception: Prelude.read: no parse
*Main

  In fact, I wasn't able to guess, what I should type so that the  
value

(A `And` A) gets parsed.

  I have ghc 6.4.1. Looking into the code of the derived instance I  
see

that it expects Text.Read.Lex.lex to return (Symbol And) for the
constructor. If I understand the code for lex correctly, then it  
parses

things as Symbol if they consist only of
[EMAIL PROTECTED]*+./=?\\^|:-~

  How then do I read values of type T defined above? Thanks in advance
for any directions.



In general, derived Read instances are designed to be inverses for  
Show.  The easy thing to do is to print values of type T and see what  
you get.  I expect that it will be in prefix form, eg:


And A A

or

And (And A A) A

etc.

That is, I think the Show and Read instances are going to ignore the  
backticks in the definition.




Cheers,
  Misha



Rob Dockins

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

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


Re: [Haskell-cafe] extreme newbie: hugs prompt vs load module

2006-08-23 Thread Robert Dockins


On Aug 23, 2006, at 10:16 AM, George Young wrote:


[linux, ghci 6.4.3.20060820, hugs May 2006]

I have just started learning Haskell.  I have hugs and ghci under
linux, and I'm going through the Gentle Introduction to
Haskellhttp://www.haskell.org/tutorial, so far through section 4,
case expressions and pattern matching.  I'm a python programmer,  
with

background in maclisp, scheme, T, C, C++, and a little J.

I'm confused about what sort of things I can type at the interpreter
prompt, and what things have to be loaded as a module.  I keep trying
to treat the prompt like a lisp or python REPL, which is obviously
wrong.  Can someone set me straight?


For the most part, the things you can enter at the GHCi or Hugs  
prompt are _expressions_.  This mostly* excludes _declarations_,  
which are things like function definitions, datatype declarations,  
class and instance declarations, etc.  Those things need to go into a  
source file.


(*) 'let' expressions will allow you to define local functions as  
part of an expression, however.  GHCi also has a slight variation of  
'let' that allows you to define functions for the session.




Is there another tutorial that might be more appropriate for me?


The following tutorial is generally recognized as one of the better  
ones:


http://www.cs.utah.edu/~hal/htut/


I am finding haskell quite appealing.  I hope to start writing real  
(if
small) applications to do some data analysis from our Postgres DB.   
Any

hints?


There are several haskell database layers.  I've had some luck with  
HDBC, which has a PostgreSQL driver.


http://quux.org:70/devel/hdbc



--George Young
--
Are the gods not just?  Oh no, child.
What would become of us if they were? (C.S. Lewis)




Rob Dockins

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



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


Re: [Haskell-cafe] implementing a csv reader

2006-08-23 Thread Robert Dockins


On Aug 23, 2006, at 3:37 PM, Henk-Jan van Tuyl wrote:



L.S.,

Reading and writing a comma seperated datafile doesn't have to be  
that complicated; the following is an easy way to read a CSV file  
into a list of tuples and display the list on screen:


For every complex problem, there is a solution which is simple,  
neat, and wrong.  -- HL Mencken



Although it seems straightforward at first, CSV suffers from text  
escaping complexities, just as does every other general purpose plain- 
text encoding.  Most notably, a newline embedded inside double quotes  
does not end a record.  These issues cause ugly corner cases if you  
aren't expecting them.  And that's just the issues with moving tables  
of strings around; if those fields have non-string interpretations  
(dates or numbers or what have you), things get really hairy.  To do  
the right thing probably requires perl-ish duck typing  :-p


See http://www.creativyst.com/Doc/Articles/CSV/CSV01.htm for a semi- 
authoritative reference on CSV.  A related RFC is here: http:// 
tools.ietf.org/html/rfc4180




Rob Dockins

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



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


Re: [Haskell] How to read one char from stdin and return immediately?

2006-08-18 Thread Robert Dockins


On Aug 18, 2006, at 8:09 AM, Haihua Lin wrote:



Hi all,

How to read one char from stdin and return immediately?
I mean there is no need to wait the user input a return.

For example:
Print y/n: 
Users input y, return immediately, no return need.

I have tried code as below, but it didn't work for me.

import IO

main = do
 hSetBuffering stdout NoBuffering
 putStr   Y/N: 
 c - getChar
 putStr (Your input is  ++ show c++.\n)

Thanks very much.



I do it this way; it should keep your buffering state consistent even  
if exceptions occur.



 bracket (hGetBuffering stdin) (hSetBuffering stdin) $ \_ - do
  hSetBuffering stdin NoBuffering
  c - hGetChar stdin
  return c



Best regards,
Haihua Lin




Rob Dockins

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



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


Re: [Haskell-cafe] Haskell wiki: most popular pages

2006-08-18 Thread Robert Dockins


On Aug 18, 2006, at 12:23 PM, Tim Walkenhorst wrote:


Bulat Ziganshin wrote:

i think that definitions with omitted arguments can be more hrd to
understand to newbie haskellers, especiallyones who not yet know the
language. as Tamas suggests, this page can be used to present to such
newbies taste of Haskell so listing all the parameters may allow to
omit unnecessary complications in this first look into language

I agree with that. The and = ... wasn't really an improvement over  
and xs = ... xs, and if the later is easier to read that's good.


Btw.:

What happened to isSpace, toLower and toUpper (, from the  
tutorial)? (I)sSpace must be there for words anyway, so I can't see  
why it's missing. (T)oLower and toUpper might have some subleties  
with internationalization and stuff, but they would be useful for  
me even as a poor man's version which can just convert A-Z, a-z  
and no umlauts.



http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data- 
Char.html



I feel that Haskell is missing some basic string manipuation  
functions, like
- replacing all occurances of one substring (or sublist) with  
another string (or list).

- tokenize a string by an arbitrary delimeter

I know many of these functions can be written in Haskell without  
much effort. But I don't really want to invent isSpace for any  
program.


Tim



Rob Dockins

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



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


Re: [Haskell-cafe] The Q Programming Language can do symbolic manipulation -- Haskell?

2006-08-16 Thread Robert Dockins


On Aug 15, 2006, at 11:43 PM, Casey Hawthorne wrote:


The Q Programming Language can do symbolic manipulation -- Haskell?

The Q Programming Language can do the following:

sqr X = X*X

==sqr 5
25

==sqr (X+1)
(X+1)*(X+1)



Can Haskell do symbolic manipulation?



Well, there's always the sledgehammer (http://www.haskell.org/ghc/ 
docs/latest/html/users_guide/template-haskell.html)




Or are term-rewriting and the lambda calculus sufficiently far enough
apart concepts?
--
Regards,
Casey
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe



Rob Dockins

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



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


Re: map and fmap

2006-08-14 Thread Robert Dockins


On Aug 14, 2006, at 3:00 PM, Iavor Diatchki wrote:


Hello,
I never liked the decision to rename 'map' to 'fmap', because it
introduces two different names for the same thing (and I find the name
`fmap' awkward).

As far as I understand, this was done to make it easier to learn
Haskell, by turning errors like Cannot discharge constraint 'Functor
X' into X =/= List.  I am not convinced that this motivation is
justified, although I admit that I have very limited experience with
teaching functional programming to complete beginners.  Still,
students probably run into similar problems with overloaded literals,
and I think, that a better approach to problems like these would be to
have a simplified learning Prelude for the beginners class, rather
than changing the standard libraries of the language (writing type
signatures probably also helps...)


This idea has been kicked around a few times, but, AFAIK, it's never  
really been fleshed out.  Has anyone ever put anything concrete on  
the table?  It seems to me that most complaints are about hard-to- 
understand error messages, and these almost always arise from  
typeclasses.  They are especially confusing when they arise from  
syntax sugar.  I suppose a prelude with no typeclasses and compiler  
options to make all syntax non-overloaded would be one way to start.


On a related note, I've seen a number of Haskell design decisions  
justified by the beginners find it difficult argument.  Is this  
argument really valid?  Is there any reason not to just tell  
beginners to use Helium?  Is there a case for something between  
Helium and full H98 (or H')?




Renaming 'fmap' to 'map' directly would probably break quite a bit of
code, as all instances would have to change (although it worked when
it was done the other way around, but there probably were fewer
Haskell programs then?).  We could work around this by slowly phasing
out 'fmap': for some time we could have both 'map' and 'fmap' to the
'Functor' class, with default definitions in terms of each other.  A
comment in the documentation would say that 'fmap' is deprecated.  At
some point, we could move 'fmap' out of the functor class, and even
later we could completely remove it.

This is not a big deal, but I thought I'd mention it, if we are
considering small changes to the standard libraries.

-Iavor



Rob Dockins

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



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


Re: [Haskell] The GHC typechecker is Turing-complete

2006-08-11 Thread Robert Dockins


On Aug 11, 2006, at 7:40 AM, Josef Svenningsson wrote:


On 8/11/06, Robert Dockins [EMAIL PROTECTED] wrote:
My purpose today is to show that the GHC typechecker with multi- 
parameter
typeclasses, functional dependencies, and undecidable instances is  
Turing-
complete.  Some time ago on this mailing list, there was a brief  
discussion
about a lambda calculus and a direct Turing-machine  
implementation; either
would be sufficient to demonstrate the Turing-completeness of the  
typechecker.
However, neither implementation was preserved on-list, and the  
links are

now dead.


Here's a link that works:
http://www.lochan.org/keith/publications/undec.html



Ah, thanks.  This is interesting because it doesn't even require  
functional dependencies.  OTOH, he uses code generation techniques to  
create the TMs in the first place...




All the best,

/Josef




Rob Dockins

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



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


[Haskell] The GHC typechecker is Turing-complete

2006-08-10 Thread Robert Dockins
This message is literate Haskell so you can all follow along at home.
The program developed in this message was tested on GHC 6.4.2.

My purpose today is to show that the GHC typechecker with multi-parameter
typeclasses, functional dependencies, and undecidable instances is Turing-
complete.  Some time ago on this mailing list, there was a brief discussion
about a lambda calculus and a direct Turing-machine implementation; either
would be sufficient to demonstrate the Turing-completeness of the typechecker.
However, neither implementation was preserved on-list, and the links are
now dead.

My strategy will be to embed the SK combinator calculus.  The SK combinator
calculus is capable of embedding the lambda calculus, which is well-known
to be Turing-complete. Furthermore, the SK calculus is simpler to implement
than the lambda calculus.

For a complete proof of Turing-completeness, one should have a correctness
proof for the embedding.  I do not undertake such a proof here, but I will
demonstrate what I hope to be convincing evidence for the correctness of
this embedding.


I begin by throwing the switches that give me the needed extensions.

 {-# OPTIONS -fglasgow-exts -fallow-undecidable-instances #-}
 module SK where

Next I define the terms of the SK combinator basis.  This includes symbols for
the combinators themselves, a symbol for application, and a way to introduce
arbitrary uninterpreted types into computations.

 data K0
 data S0
 data App x y
 data Other a

Now I proceed to create the evaluator by first defining a single-step reduction
relation.  This relation is carefully designed to be reflexive on normal forms,
and always reduces the leftmost-outermost redex.  I then form the final
evaluation relation by taking the transitive closure of single-step reduction.

The semantics of typeclass constraint satisfaction are basicly strict.  That
is, the typechecker will make sure to fully evaluate all class constraints
and fully instantiate all types whether or not those types turn out to be
needed.  Because of this, I need to be careful to form the transitive closure
in a way that doesn't cause the typechecker to diverge on evaluation when it
should not (of course, the typecheker will diverge on divergent terms).

In order to do this, I define the single-step reduction relation so that it
returns an additional result in addition to the reduced term.  This result
indicates 'More' whenever a redex was found and reduced and 'Done' otherwise.

A few reduction rules perform reduction in parallel.  These rules will return
'More' if reduction was performed on any subterm.

 data Done
 data More

 class CombineDone d1 d2 d | d1 d2 - d
 instance CombineDone Done Done Done
 instance CombineDone Done More More
 instance CombineDone More Done More
 instance CombineDone More More More


The 'Eval1' relation performs a single step of reduction.  The presentation
of this relation is somewhat tedious because we are forced to enumerate each
possible spine shape up to 4 'App's deep.  I could possibly do this more
concisely if I enabled overlapping instances.

 class Eval1 x y d | x - y d

I start by providing axioms stating that atomic terms evaluate to themselves
with no reduction.

 instance Eval1 S0S0 Done
 instance Eval1 K0K0 Done
 instance Eval1 (Other a) (Other a)  Done

There are a number of cases which just propagate evaluation contexts underneath
the right-hand side of of 'App' when the spine shape cannot be reduced any
further.  These fairly uninteresting cases are collected together here.

 instance Eval1 x x' d = Eval1 (App K0 x) (App K0 x') d
 instance Eval1 x x' d = Eval1 (App S0 x) (App S0 x') d
 instance ( Eval1 x x' d1
  , Eval1 y y' d2
  , CombineDone d1 d2 d
  ) = Eval1 (App (App S0 x) y) (App (App S0 x') y') d

 instance Eval1 x x' d = Eval1 (App (Other a) x) (App (Other a) x') d

 instance ( Eval1 x x' d1
  , Eval1 y y' d2
  , CombineDone d1 d2 d
  ) = Eval1 (App (App (Other a) x ) y )
 (App (App (Other a) x') y') d

 instance ( Eval1 x x' d1
  , Eval1 y y' d2
  , Eval1 z z' d3
  , CombineDone d1 d2 d4
  , CombineDone d3 d4 d
  ) = Eval1 (App (App (App (Other a) x ) y ) z )
 (App (App (App (Other a) x') y') z') d

Now we get to the real meat.  Here are the rules for reducing the 'K'
combinator.  There are rules for reducing under both 2 and 3 'App's.

 instance Eval1  (App (App K0 x) y) x More
 instance Eval1 (App (App (App K0 x) y) z) (App x z)  More

And here, the rule for reducing the 'S' combinator.

 instance Eval1 
 (App (App (App S0 f) g) x)
 (App (App f x) (App g x))
 More

Finally, a rule to decompose an arbitrary 'App' context. I propagate
the evaluation context down the left side of an 'App' only when that
'App' is not involved in any redexes. This implements the leftmost-

Re: [Haskell-cafe] Why Not Haskell?

2006-08-09 Thread Robert Dockins

On Aug 8, 2006, at 5:36 PM, Albert Lai wrote:


Brian Hulley [EMAIL PROTECTED] writes:


Also, the bottom line imho is that Haskell is a difficult language to
understand, and this is compounded by the apparent cleverness of
unreadable code like:

 c = (.) . (.)

when a normal person would just write:

 c f g a b = f (g a b)


All mainstream languages are also difficult to understand, with
similarly clever, unreadable code.  Let's have a fun quiz!  Guess the
mainstream languages in question:


[snip]


2. What language allows you to test primality in constant runtime?
   That is, move all the work to compile time, using its polymorphism.


GHC-Haskell (with enough extensions enabled)?  We're most of the way  
there already with type arithmetic.  I bet putting together a nieve  
primality test would be pretty doable.  In fact, I suspect that GHC's  
type-checker is turing-complete with MPTCs, fundeps, and undecidable  
instances.  I've been contemplating the possibility of embedding the  
lambda calculus for some time (anybody done this already?)


Oops.  I see now the qualifier mainstream.  The point still stands,  
however.



Rob Dockins

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



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


Re: [Haskell-cafe] Abstract Data Types

2006-08-09 Thread Robert Dockins


On Aug 9, 2006, at 5:27 AM, Johan Grönqvist wrote:


Hi,

I have a question:

Short version: If I want to hide the implementation of a data-type  
Stack a from the rest of the program,  do I need to put its  
definition in a separate file?




This is the usual way, as you've probably gathered.



Long version:

I want to use a stack, and I might implement it as a list, but I  
want to hide the implementation from the rest of the program. This  
is how I understand abstract data type.


In The Craft of Functional Programming, this seems to be  
implemented by putting each data type into a separate module and  
only exporting parts of the definitions.


In The Haskell School of Expression, this seems not to be used at  
all.


In the lecture notes at (http://www.dcs.shef.ac.uk/~mps/courses/ 
com2020/adts.pdf), type classes are used for abstract data types.  
It seems to me that this approach does not hide any parts of any  
definition, but only requires that all instances of class stack  
have functions pop and push of the correct types. I am interested  
in hiding parts of definitions.


In the report, I did not find any mention of a requirement to have  
different modules in separate files, but I have not managed to put  
several modules in the same file using ghci.



I think all current implementations require separate files for  
separate modules, although I believe you are correct that is is not  
required by the report.



I would like to keep my small program in one literate-haskell tex- 
file and still be able to hide some definitions from others.


Is this possible?

One option would of course be to write a script that separates the  
code into different and then compiles the entire program.




There are two other basic ways that I know of to achieve data type  
abstraction.



1) Parametric polymorphism

Create a typeclass with the appropriate operations.  Then, in  
functions which use stack operations, always write, eg:



doSomething :: Stack s = s a - Bool

rather than

doSomething :: ConcreteStackType a - Bool



This is abstraction at the point of use if you will.  You'll see  
this technique pretty often used to abstract over different Monads,  
for example.




2) Exestential datatypes.  You can create a sort of poor-man's  
substitute for ML style module systems by using existential data  
types.  Its a little fiddly, but it mostly works:



{-# OPTIONS -fglasgow-exts #-}

import Data.Maybe (isJust)


data StackRec a = forall s. Show (s a) = StackRec (s a) (a - s a -  
s a) (s a - s a) (s a - Maybe a)

listStackRec =
   StackRec
  []
  (:)
  (\xs - case xs of (_:ys) - ys; [] - [])
  (\xs - case xs of (y:_) - Just y; [] - Nothing)


fauxModule :: IO ()
fauxModule =
  case listStackRec of { StackRec empty push pop peek - do

print (isJust (peek (pop (pop (push 'a' empty)
print (push 'b' empty)

-- doesn't typecheck
--print (push 'c' [])

  }

main = fauxModule




Unfortunately, the case statement gives you monomorphic bindings for  
the stack methods, and let bindings don't play nice with  
existentials.  I'm not sure if there's a way around this or not.




Thanks in advance!

/ johan grönqvist



Rob Dockins

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



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


Re: [Haskell] thread-local variables

2006-08-05 Thread Robert Dockins
Sorry to jump into this thread so late.  However,  I'd like to take a moment 
to remind everyone that some time ago I put a concrete proposal for 
thread-local variables on the table.

http://article.gmane.org/gmane.comp.lang.haskell.cafe/11010

I believe this proposal addresses the initialization issues that Einar has 
been discussing.  In my proposal, thread-local variables always have some 
defined value, and they obtain their values at well-defined points.

The liked message also gives several use cases that I felt motivated the 
proposal.

--
Rob Dockins

Talk softly and drive a Sherman tank.
Laugh hard, it's a long way to the bank.
   -- TMBG
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell-cafe] Why shouldn't variable names be capitalized?

2006-08-04 Thread Robert Dockins


On Aug 4, 2006, at 1:12 PM, Martin Percossi wrote:

Hi, I'm wondering what the rationale was for not allowing  
capitalized variable names (and uncapitalized type names and  
constructors). I can only think of two arguments, and IMHO both of  
them are bad:


1. Enforces a naming convention. Fine - but my view is that this  
doesn't belong in the language definition (it belongs in the user's  
coding standards). I get annoyed, for example, that when I write  
code that manipulates matrices and vectors, I can't refer to the  
matrices with capital letters as is common in the literature.


This is occasionally irritating.

And to anyone who says that it's good to enforce naming  
consistency, I have this to say: Any language that requires me to  
learn about category theory in order to write imperative code  
should treat me like an adult when it comes to the naming of  
variables as well. ;-)


2. It makes it easier to write the compiler. I don't think I need  
to explain why this is bad...


Eh?  I'm not convinced this is a bad reason.  It obviously needs to  
be balanced against other competing factors, but ease of  
implementation should always a consideration when designing a language.



3. It removes a whole class of possible ambiguities from the  
language.  You the programmer (and the compiler, as an added bonus)  
can always identify the syntactic class of an identifier from _purely  
local_ context.


Suppose I remove the case restriction.  Is the following a pattern  
match or a function definition?  Is M a variable or a data constructor?


   let f x M = z M in 

You can't tell!  Worse, it could change depending on what identifiers  
are in scope.  It could happen that you import a module and it  
silently causes your function definition to change to a pattern  
match.  The situation is similar with type classes and type  
variables.  You could magically end up with an instance declaration  
that is less polymorphic than you expect (if you have extensions  
turned on).


I imagine that someone is just itching to sort me out. Do your  
worst! ;-)


Thx
Martin



Rob Dockins

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



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


Re: [Haskell-cafe] Edison StandardSet has inefficient function implementation

2006-08-03 Thread Robert Dockins

On Aug 3, 2006, at 7:14 AM, Ahn, Ki Yung wrote:

Edision does not yet have all the asymtotic description of its  
functions.


Indeed.  This is a big job which requires a lot of time, attention to  
detail, and a pretty good working understanding of lazy amortized  
analysis.  Unfortunately I'm currently lacking in categories 1 and 3...


Many of the bounds can be obtained from the referenced papers.  I'll  
work on adding those as I am able.



I got the Edision 1.2 source and looked into the code whether the
container implementations meet the expected asymtotic bounds.



In the module Data.Coll.StandardSet which packages Data.Set,
some functions which can be O(log n) is implemented as O(n).

Data.Set has a split and splitMember running in O(log n).
With those functions we can implement OrdCollX operations like
filterLT, filterLE, filterGT, filterGE,
partitionLT_GE, partitionLE_GT, partitionLT_GT all in O(log n).
However, only partitionLT_GT was O(log n) implemended using split.
All other function implmentation just used its axiomaic description
using CollX operations like filter and partition, which is O(n).


Thanks for pointing this out.  filterLT and filterGT can indeed be  
written in terms of split; I just missed that somehow.


For the others, however, splitMember won't suffice.  The problem here  
is that splitMember doesn't return the equal member from the  
original set, it just returns a Bool indicating whether the set  
contained and equal element.  As of now, Edison is supposed to  
guarantee that, for observable collections, you will always get back  
the identical object(s) that you put in.  This accounts for the fact  
that you may supply an Eq instance which is only a weak equivalance,  
that is, even if x == y returns true, x and y may be distinguishable  
in some way.


I am considering dropping this guarantee in a future version of  
Edison, because I think its value is highly dubious.  (Using a set or  
bag with a weak element equivalence is really just creating a finite  
map/relation.  If you need a finite map/relation you should just  
_use_ a finite map/relation!)  If I dropped the guarantee, I could  
indeed implement the other operations as you suggest.





It needs to be fixed.

P.S. I haven't checked the darcs version yet.

--
Ahn, Ki Yung



Thanks for your comments!



Rob Dockins

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



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


Re: [Haskell-cafe] The difficulty of designing a sequence class

2006-08-01 Thread Robert Dockins


On Jul 31, 2006, at 10:27 PM, John Meacham wrote:

[snip]



It is best to think of haskell primitives as something completely new,
they reuse some naming conventions from OO programming, but that  
doesn't

mean they suffer from the same limitations. It took me a few trys to
wrap my brain around it. I liken learning haskell to tipping over a
vending machine. you can't just push it, you gotta rock it back and
forth a few times building up momentum until bam! suddenly the  
flash of

insight hits and it all makes sense.



Do you have a lot of personal experience attaining zen-like insight  
by tipping over vending machines? I'll have to try that some time ;-)


*chucke*

Thanks for making me laugh this morning.




John



Rob Dockins

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



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


[Haskell-cafe] Future Edison directions

2006-08-01 Thread Robert Dockins

Hello all,

There has been very recently a thread discussing the design decisions  
involved in creating a sequence abstraction.  This was naturally of  
interest to me as the current Edison maintainer, and generated a fair  
bit of interesting discussion.  I'd like to kick off a new thread  
here to talk about future directions for the Edison API in particular.


1) Regarding Sequence, I have become convinced by the discussion that  
the Edison Sequence class should be broken down into smaller  
classes.  Furthermore, it would be very nice to make these smaller  
classes shared across the various families of data structure  
abstractions in Edison (Sequences, Collections and Associative  
Collections).  The formulation of Sequence of kind * - * may need to  
be sacrificed to this end.  I am not convinced that losing the maps  
and zips would be a major blow; however there are a couple of  
strategies for retaining them in some form.


2) The associated collection API is in a similar situation, except  
there are no zips.


3) I am reluctant to undertake a major overhaul of the Edison API  
while the future of type classes in Haskell' is so hazy.  I haven't  
heard any news from the Haskell' type classes focus group in quite  
some time, and last I was aware, discussion was somewhat stalled.  I  
there any hope for a coherent story here in the nearish future?


4) I am on the verge of deciding that nobody wants non-observable  
collections (ie, collections in which the element values are not  
available for inspection).  Currently Edison has no implementations  
which are non-observable, and I am not aware of anyone else creating  
a datastructure implementation in Haskell which is non-observable.   
Therefore, I am considering removing this feature of the Edison  
typeclass hierarchy to reduce complexity.  Shout if you think this  
would be a terrible mistake.


5) OTOH, something people DO seem to want is collection views, or  
the ability to treat a datastructure as though it were something  
else.  For example, it would be nice to transparently treat the keys  
of a finite map as a set, or to treat a nested sequence as a single  
flattened sequence.  Such uses require the separation of operations  
which can create datastructures from those which merely inspect them  
(or some fancy bidirectional stuff I don't think I want to get into).


6) Edison 1.2 has now been out for a couple of months.  If you've  
used or looked at the new Edison, I'd love to hear what you think.  I  
think the next development cycle will involve pretty substantial  
changes, and if you want to get your gripes addressed, now is a good  
time to voice them.  Alternately, if you think there are some aspects  
that are very important to keep, that's also good information.


7) Finally, I somehow feel like there should be a nice categorical  
formulation of these datastructure abstractions which would help to  
drive a refactoring of the API typeclasses in a principled way,  
rather than on an ad-hoc I-sort-of-think-these-go-together sort of  
way.  Unfortunately, my category-fu is quite weak, so all I have is  
this vague intuition that I can't substantiate.  I'm sort of familiar  
with initial algebras, but I think they may be too concrete.  I'm  
looking for some way to classify algebras that have, eg, the property  
of having folds, or of being set-like, etc.  If anybody can point me  
in the right direction wrt this, that would be great.




Rob Dockins

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



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


Re: [Haskell-cafe] The difficulty of designing a sequence class

2006-07-31 Thread Robert Dockins

On Jul 30, 2006, at 5:28 PM, Brian Hulley wrote:

Robert Dockins wrote:

On Sunday 30 July 2006 07:47, Brian Hulley wrote:

Another option, is the Edison library which uses:

 class (Functor s, MonadPlus s) = Sequence s where

so here MonadPlus is used instead of Monoid to provide empty and
append. So I've got three main questions:



1) Did Edison choose MonadPlus just because this fitted in with the
lack of multi-parameter typeclasses in H98?

Edison's design hails from a time when MPTCs were not only
non-standard (as they still are), but also not widely used, and
before fundeps were avaliable (I think).  So the answer to this one
is pretty much yes.

[snip]

Hi - Thanks for the answers to this and my other questions. One  
thing I just realised is that there doesn't seem to be any instance  
declarations anywhere in the standard libs relating Monoid to  
MonadPlus so it's a bit unsettling to have to make a random  
choice on the question of what kind of object a Sequence is...


I tried:

   class (forall a. Monoid s a) = Sequence s where ...

but of course that doesn't work, so I suppose MonadPlus is the only  
option when 'a' doesn't appear as a type variable arg of the class  
being defined.



BTW, for what purpose are you desiging a new sequence class?  You are
clearly aware of other efforts in this area; in what ways to they not
meet your needs?


The existing sequence and collection classes I've looked at don't  
do enough.


For example, when I tried to represent the text in an edit widget,  
I realised I needed a sequence of characters that could also be  
considered to be a sequence of lines, and it is necessary to be  
able to index the sequence by character position as well as by line  
position, as well as keeping track of the total number of  
characters, the total number of lines, and the maximum number of  
characters on any one line (so as to be able to calculate the x,y  
extents when laying out the widget, assuming a fixed width font  
(tabs ignored!)), with very efficient split and append operations.


So, what you want is a sequence of sequences that can be  
transparently converted to a flattened sequence and vice versa? And  
you also want to keep track of the total number of lines and  
characters within each line.  Additionally, you want to keep track of  
the maximum number of characters in any one line.


I managed to get a good representation by using a FingerTree of  
lines where each line uses a ByteString.
I made my own FingerTree class based on the one referenced in the  
paper at http://www.soi.city.ac.uk/~ross/papers/FingerTree.html but  
without the symbolic names which I find totally unreadable and  
confusing, and also so I could get full control of the strictness  
of the implementation, and also as a way of understanding them  
since I'd never come across such a complicated data structure  
before. (I highly recommend this paper to anyone who wants to learn  
about FingerTrees, Monoids and other very useful concepts.)


So one thing existing sequence classes don't have (apart from  
FingerTree) is the concept of measurement which is essential when  
you want efficient updates. Eg in my text buffer, the measurement  
maintained for a sequence is the number of chars and number of  
lines and maximum line length.


Edison has support for transparently keeping track of the size of a  
sequence.


http://www.eecs.tufts.edu/~rdocki01/docs/edison/Data-Edison-Seq- 
SizedSeq.html


It may well be possible to create a slightly generalized wrapper that  
keeps track of arbitrary measures.  (If they can be computed by a  
function which is associative, commutative and has a unit).

Humm, sort of an incremental fold I like it.

Then I needed a structure for a Trie widget a bit like (details  
omitted):


 data Node = Expanded Value T | Collapsed Value T | Leaf Value
 newtype T = T (FingerTree (Key, Node))

where objects of type T could be regarded as a finite map (eg from  
hierarchical module names to modules) as well as a flattened linear  
sequence indexed by line number (for display on the screen in a  
widget given the current scroll bar position), and which also  
needed to keep track of the total horizontal and vertical extent of  
the Trie as it would appear in the widget's font.


There are several different kinds of measurement going on in this  
data structure, as well as the complexity of the extra recursion  
through the leaf to a new level. Existing sequence abstractions  
don't seem to provide the operations needed to treat a nested data  
structure as a single sequence.


In summary:

1) Often a complex data structure must be able to be simultaneously  
regarded as a single flattened sequence
2) Measurements are needed for efficient updates (may need to keep  
track of several at once)
3) Indexing and size are sometimes needed relative to the flattened  
sequence not just the top level
4) It is useful to have a finite map that can also

Re: [Haskell-cafe] The difficulty of designing a sequence class

2006-07-30 Thread Robert Dockins
On Sunday 30 July 2006 07:47, Brian Hulley wrote:
 Hi -

 Part 1 of 2 - Monoid versus MonadPlus
 ===

 I've just run into a troublesome question when trying to design a sequence
 class:

 class ISeq c a | c - a where
  empty :: c
  single :: a - c
  append :: c - c - c

 However I've noticed that people sometimes separate the empty and append
 operations out as sequences with these ops form a Monoid therefore:

  class Monoid c = ISeq c a | c - a where
  single :: a - c

  -- now outside the class
  append :: ISeq c a = c - c - c
  append = mappend

  empty :: ISeq c a = c
  empty = mempty

 Another option, is the Edison library which uses:

  class (Functor s, MonadPlus s) = Sequence s where

 so here MonadPlus is used instead of Monoid to provide empty and append.
 So I've got three main questions:

 1) Did Edison choose MonadPlus just because this fitted in with the lack of
 multi-parameter typeclasses in H98?

Edison's design hails from a time when MPTCs were not only non-standard (as  
they still are), but also not widely used, and before fundeps were avaliable 
(I think).  So the answer to this one is pretty much yes.  I've considered 
reformulating the Sequence class to be more similar to the Collection classes 
(which use MPTCs, fundeps and mention the element type), but for the 1.2 
version I wanted to make as few changes as I thought I could to the overall 
design decisions.

In fact, I will likely make this change at some point.  It would allow, eg, 
making Don's ByteString (or whatever it's called now, I forget) an instance 
of Sequence, which is currently impossible.  OTOH, it would require 
sacrificing the Functor, Monad and MonadPlus instances...

 2) Are there any reasons to prefer the Edison design over the MPTC design
 (apart from H98 compatibility) or vice versa?

H98 is probably the big one.  I'm currently in wait-and-see mode concerning 
MPTCs and especially fundeps.  As Edison maintainer, I've tried to use them 
sparingly in the hope that Edison can be made Haskell' compliant (crosses 
fingers).  Aside: I hope the Haskell' committee makes some sort of decision 
here soonish.

 3) Is it worth bothering to derive ISeq from Monoid (with the possible
 extra inefficiency of the indirection through the definitions for append =
 mappend etc or does the compiler completely optimize this out)?

Not sure about this one.  I suspect, however, that the appropriate SPECIALIZE 
pragmas could cover any cases that you really care about.

 and a fourth more long term question:

 4) Would it be worth reconsidering the rules for top level names so that
 class methods could always be local to their class (ditto for value
 constructors and field names being local to their type constructor).

[snip more question]

No comment.

 Part 2 of 2 - Monad versus Ancillary result type
 

 Another issue relates to left and right views of a sequence. If a sequence
 is non-empty, the left view is just the leftmost element and the rest of
 the sequence. The problem arises when the sequence is empty. In the Edison
 library, this is solved by returning a monadic value ie:

  lview :: Monad m = s a - m (a, s a)

 whereas from the paper Finger trees: a simple general purpose data
 structure by Ralf Hinze and Ross Paterson they use an ancillary data type
 to store the result of a view:

 data ViewL s a = NilL | ConsL a (s a)

 viewL :: FingerTree a - ViewL FingerTree a

 So my question here is: what's the best choice? I can see that the monadic
 version has the advantage that it could be used in do notation in cases
 where you expect the sequence to be non-empty, but has the disadvantage
 that it treats the empty sequence as something special (resulting in
 Monad/fail) and an extra indirection to find the components when the
 sequence is non-empty.

Well, the empty sequence IS special, when it comes to looking the leftmost 
(resp. righmost) element.  You have to deal somehow with the fact that the 
operation is a partial function.

I think the arbitrary monad option is better.  It gives the user more 
flexibility about how to use the operation.  Really the only way to use ViewL 
is to put it inside a case of.  With a monad you can use any of the 
plethora of monadic operations and, as you mentioned, the do notation.  In 
addition, if you want the use case of ViewL, you can always use the Maybe 
monad.

I'm not inclined to worry too much about the extra indirection, which seems 
like a viable target for being erased by the compiler (I've not tested if 
this happens, however).


 Anyway these are my main questions for now - any feedback appreciated ;-)


BTW, for what purpose are you desiging a new sequence class?  You are clearly 
aware of other efforts in this area; in what ways to they not meet your 
needs?


 Thanks, Brian.


-- 
Rob Dockins

Talk softly and drive a Sherman tank.
Laugh hard, 

Re: [Haskell] String permutation

2006-07-26 Thread Robert Dockins


On Jul 26, 2006, at 12:44 AM, Sukit Tretriluxana wrote:


Dear expert Haskellers,

I am a newbie to Haskell and try to write several algorithms with  
it. One of them is the string permutation which generates all  
possible permutations using the characters in the string. For  
example, if I say,


permute abc

It will return the the result as

[abc,acb,bca,bac,cab,cba]



[snip]

 I am more than certain that this simple program can be rewritten  
to be more succinct and possibly more efficient using Haskell's  
features. So I would like to ask if any of you would kindly show me   
an example.



About the shortest way I can think of, using the good ol' list  
monad.  This isn't exactly efficient, but there you are...



import Data.List

permute :: String - [String]
permute [] = [[]]
permute str = do
   x  - str
   xs - permute (delete x str)
   return (x:xs)



Rob Dockins

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



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


Re: [Haskell-cafe] Re: ANN: System.FilePath 0.9

2006-07-26 Thread Robert Dockins


On Jul 26, 2006, at 1:47 PM, Neil Mitchell wrote:


Hi,


Perhaps instead:

   directoryOf :: FilePath - String
   filenameOf  :: FilePath - String
   extensionOf :: FilePath - String
   basenaneOf  :: FilePath - String

   replaceFilename  = joinFilePath . directoryOf
   replaceDirectory = flip joinFilePath . filenameOf


Trying to design a consistent naming system, it helps if we all agree
on what the various parts of a filepath are called, this is my draft
of that:

http://www-users.cs.york.ac.uk/~ndm/temp/filepath.png

With a better name for basename, if anyone can think of one.


stem, perhaps?  You could also, maybe, distinguish the short  
stem (everything before the extensions) from the long stem  
everything before the extension.




Once we have that, how about

takeElement :: FilePath - String
dropElement :: FilePath - String
replaceElement :: FilePath - String - FilePath
addElement :: FilePath - String - FilePath
splitElement :: FilePath - (String, String)
joinElement :: String - String - FilePath

With the restriction that not all of these are provided. Some don't
make sense (splitBaseName, dropBaseName), some are implemented via
combine (addFileName, joinFileName), some are redundant (addExtensions
== addExtension)

I'm also debating whether split/join should be exported, since they
are less likely to be used and can easily be written as a take/drop
pair. And of course, a bigger interface is harder to understand.

Opinions on this? It's easier to tweak a specification than the  
actual code :)


Thanks

Neil



Rob Dockins

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



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


Compile problem on Windows

2006-07-14 Thread Robert Dockins
I posted a message on the libraries list a couple of days ago about a  
compile problem I'm having.  I haven't got any nibbles.  Because I  
now suspect this is a GHC problem, I'm posting here to see it I can  
get this resolved.  Rather than repost the details, allow me to refer  
you to (http://permalink.gmane.org/gmane.comp.lang.haskell.libraries/ 
4873) which contains a complete description of the problem.  As far  
as I can tell, the GHC install is missing a necessary system header,  
or it isn't being found, or somesuch.  I tried crawling through the  
headers to find out what the problem is, but, as per usual, the  
system headers are almost totally incomprehensible.


I've tried using both Cygwin and MSYS shells, but the results are  
identical.  As I said in the above message, I'm not very familiar  
with this environment, so I'd appreciate pointers in the correct  
direction if I've made some mistake.



Thanks

Rob Dockins

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



___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Compile problem on Windows

2006-07-14 Thread Robert Dockins

On Jul 14, 2006, at 12:26 PM, Esa Ilari Vuokko wrote:


On 7/14/06, Robert Dockins [EMAIL PROTECTED] wrote:

I posted a message on the libraries list a couple of days ago about a
compile problem I'm having.  I haven't got any nibbles.  Because I


Sorry, it slipped past me.  The reason nobody reacted might also be
that it's not really ghc's problem, but problem in mingw/winapi  
headers

which ghc just drags along.


now suspect this is a GHC problem, I'm posting here to see it I can
get this resolved.  Rather than repost the details, allow me to refer
you to (http://permalink.gmane.org/gmane.comp.lang.haskell.libraries/


http://permalink.gmane.org/gmane.comp.lang.haskell.libraries/4873
(hopefulyl it's on one line in my mail)


4873) which contains a complete description of the problem.  As far
as I can tell, the GHC install is missing a necessary system header,
or it isn't being found, or somesuch.  I tried crawling through the
headers to find out what the problem is, but, as per usual, the
system headers are almost totally incomprehensible.


I'm just guessing here, but reading the sql.h and sqltypes.h it seems
likely to me that you should include windows.h before including them.
If it is so, it very likely is not a bug in ghc or winapi-package  
from mingw,
but intentional.  Fix would be to add #include windows.h in  
the .hsc file.


Ah, but that's so simple!  Thanks, that fixed the problem.


I've tried using both Cygwin and MSYS shells, but the results are
identical.  As I said in the above message, I'm not very familiar
with this environment, so I'd appreciate pointers in the correct
direction if I've made some mistake.


In generla, using cygwin shell with cabal and/or packages with  
configure
and using non-cygwin-ghc (cygwin port of ghc isn't maintained or  
built)

can lead to wierd problems.  Msys sometimes works, sometimes doesn't,
depending how aware packages are ghc's and msys' mingws' paths.


Humm.  What do people usually do?  Use cmd.exe? *cringes at the thought*



HTH,
--Esa



Rob Dockins

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


___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: [Haskell-cafe] Comma in the front

2006-07-13 Thread Robert Dockins


On Jul 12, 2006, at 9:18 PM, Joel Reymont wrote:


Are cool kids supposed to put the comma in front like this?

, foo
, bar
, baz

Is this for historical or other reasons because Emacs formats  
Haskell code well enough regardless.


Thanks, Joel



I personally like this style.  It's a little hard to say why, but let  
me attempt.  I think it's related to layout.  Layout trained me to  
regard the end of lines as uninteresting, and the beginning as  
interesting.  Thus, I forget to put separators at the ends of lines  
(freedom from the tyranny of the semicolon!), but I always notice if  
a comma or semicolon is missing at the beginning of a line.  Its very  
obvious because they're all aligned vertically and, as I said,  
Haskell trains you to notice the leading edges of lines if you use  
layout.  It also makes it very visually obvious where the list/tuple/ 
do block ends when you line up the brackets with the separators.


IMO the patch/diff/darcs issue is a red herring.  It sounds like an  
after the fact justification to me.



Rob Dockins

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



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


[Haskell] Lrc status

2006-07-11 Thread Robert Dockins
Does anyone have any information about the current status of Lrc?   
Has it ever been released?  Does it live somewhere else now?


The homepage is apparently:  http://www.di.uminho.pt/~jas/Research/ 
LRC/lrc.html


It has a bunch of coming soon links, but the page hasn't been  
updated since about 2002.



Rob Dockins

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



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


Re: [Haskell-cafe] help with creating a DAG?

2006-07-08 Thread Robert Dockins
On Saturday 08 July 2006 12:25 pm, David Roundy wrote:
 Hi all,

 I'm wanting to create a data structure to hold a directed acyclic
 graph (which will have patches represented by edges), and haven't yet
 been able to figure out a nice representation.  I'd like one that can
 be reasoned with recursively, or as closely to recursively as
 possible.  The problem is one of dependency relations between darcs
 patches, and normally reduces to a simple tree, with conflict
 resolution patches bringing branches of the tree back together.  Trees
 I know how to handle intuitively and elegantly, but DAGs are a whole
 different question.

 I looked for papers, and there was one on an initial-algebra approach
 to DAGs that looked promising, but I'm afraid I wasn't able to fully
 understand it, and it is able to describe more complicated DAGs than
 I'd like to support.

 Anyhow, any suggestions from persons with experience with this sort of
 thing would be great.  These are getting to be data structures that
 are more complicated than anything I'm comfortable with.  :(


Is there some reason you don't want to use FGL?

http://web.engr.oregonstate.edu/~erwig/fgl/haskell/
http://haskell.org/ghc/docs/latest/html/libraries/fgl/Data-Graph-Inductive.html



-- 
Rob Dockins

Talk softly and drive a Sherman tank.
Laugh hard, it's a long way to the bank.
   -- TMBG
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Prefix/Infix operators

2006-07-07 Thread Robert Dockins


On Jul 7, 2006, at 8:57 AM, Sara Kenedy wrote:


Hello everybody,

I checked the topics in Haskell-Cafe about prefix/infix operators but
I did not find them. Now I bring my questions to here to ask you.

1) I have a Common-Lisp code representing an expression result as  
follows

((MPLUS SIMP)
  ((MTIMES SIMP) ((RAT SIMP) 1 2) ((MEXPT SIMP) $X 2))
  ((MTIMES SIMP) ((RAT SIMP) 1 3) ((MEXPT SIMP) $X 3)))

2) I attempted to change it to mathematics operators, replacing

MPLUS SIMP - +
MEQUAL SIMP - =
RAT SIMP   - /
MEXPT SIMP - ^


[snip some code]


3) And NOW I want to transfer from prefix operator into infix
operator, for example: From
((+)
  ((*) ((/) 1 2) ((^) x 2))
  ((*) ((/) 1 3) ((^) x 3)))

in to the expression: 1/2*x^2+1/3*x^3

I try to figure out it, but this time it is not successfully. If you
are familiar with that, please share with me. Many thanks to all.


If I were approaching this problem, I'd probably think of it like a  
very small compiler.  That is, I would 1) define the abstract syntax  
as a algebraic data type 2) parse the S-expression into the abstract  
syntax and 3) pretty-print the new concrete syntax with infix operators.


Even for a language as small as this one, I think the benefits of  
approaching the problem in a modular way outweigh the overhead.  I  
think it would be very difficult to get, eg, operator precedence  
correct by just doing text manipulations on the string.


Of course, since the source is s-expressions anyway, there's always  
the option of writing a lisp macro to do the whole thing and thereby  
get parsing for free.



As a mostly related aside, here's a cool looking tutorial google  
turned up about writing a scheme interpreter in Haskell:


http://halogen.note.amherst.edu/~jdtang/scheme_in_48/tutorial/ 
overview.html




Rob Dockins

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


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


[Haskell-cafe] Re: [Haskell] Re: ANNOUNCE: HNOP 0.1

2006-06-30 Thread Robert Dockins

[moved to cafe]

On Jun 30, 2006, at 4:01 AM, Ashley Yakeley wrote:


In article
[EMAIL PROTECTED] 
,

 Bayley, Alistair [EMAIL PROTECTED] wrote:


Cool, that's awesome. But I don't see any Haddock docs? Or a Cabal
Setup.hs? Would it be much trouble to add them?


Bear in mind HNOP compiles just to an executable file, so it doesn't
really have a Haskell API.

One interesting line of development would be to spin off the core
functionality into a separate library, to provide no-op services to
other Haskell applications.



I'm sorry; I know this is a serious discussion (either that or  
everyone involved in this discussion has a more subtle sense of humor  
than I), but this sentence made me laugh out loud...  :-)


no-op services?  That's just great!



I'm thinking something like this:

  noop :: IO ()  -- generalise to other Monads?

This would actually not be too hard to write, given my existing work,
and then of course the executable would simply be a thin wrapper.

--
Ashley Yakeley
Seattle WA




Rob Dockins

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

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


Re: [Haskell-cafe] Packages and modules

2006-06-25 Thread Robert Dockins
On Sunday 25 June 2006 05:16 am, Brian Hulley wrote:
 Hi -
 At the moment there is a problem in that two packages P and Q could contain
 the same hierarchical module eg Data.Foo, and the only way for user code to
 ensure the right Data.Foo is used is to ensure that packages P and Q are
 searched in the right order.
 However suppose P and Q also contain another module with the same name, eg
 Data.Bar.
 And suppose a user module wants to use Data.Foo from P but Data.Bar from
 Q!!!

 I'm wondering: would it not be easier to just make it that the package name
 is prepended to the hierarchical module name, so the modules would instead
 be called by the names P.Data.Foo and Q.Data.Bar?

[snip discussion of this idea]

The idea of improving the module system has been discussed a number of times 
before.  Here is a thread started by a suggestion from the simons which 
generated a fair bit of discussion:

http://www.haskell.org/pipermail/libraries/2003-August/001310.html

I'm not sure whatever became of this idea; discussion seemed to sort of reach 
a consensus, and then nothing happened.

The module grafting mechanism always seemed kind of nice to me.  I think 
some of the problems discussed in this thread could be by using cabal, 
especially to specify the graftings expected for compilation.  It seems like 
grafting can give a plausible story for dealing with dynamicly loaded code, 
which is a nice bonus.


-- 
Rob Dockins

Talk softly and drive a Sherman tank.
Laugh hard, it's a long way to the bank.
   -- TMBG
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Functional progr., images, laziness and all therest

2006-06-22 Thread Robert Dockins


On Jun 22, 2006, at 10:16 AM, Brian Hulley wrote:


minh thu wrote:

2006/6/22, Brian Hulley [EMAIL PROTECTED]:

Jerzy Karczmarczuk wrote:

Brian Hulley wrote:

[snip]
y IS NOT a longer list than yq, since co-recursive equations  
without

limiting cases, apply only to *infinite* streams. Obviously, the
consumer of such a stream will generate a finite segment only, but
it is his/her/its problem, not that of the producer.

I still don't understand this point, since y = (a*x0 : yq) so surely
by induction on the length of yq, y has 1 more element?

y and yq are infinite...


But how does this change the fact that y still has 1 more element  
than yq?

yq is after all, not a circular list.
I don't see why induction can't just be applied infinitely to prove  
this.


Induction doesn't apply to co-inductive objects, such as infinite  
lists AKA streams.


I particular, the length of an infinite list is undefined, much as  
the size of an infinite set is undefined.  The only think you can  
discuss, a la Cantor, is cardinality.  In both cases, as mentioned by  
another poster, it is aleph-null.


aside
Every few months a discussion arises about induction and Haskell  
datatypes, and I feel compelled to trot out this oft-misunderstood  
fact about Haskell: 'data' declarations in Haskell introduce co- 
inductive definitions, NOT inductive ones.  Induction, in general,  
does not apply to ADTs defined in Haskell; this is in contrast to  
similar-looking definitions in, eg, ML.  This is a common source of  
confusion, especially for mathematically-inclined persons new to  
Haskell.  Does anyone know of a good reference which clearly explains  
the difference and its ramifications?  I've never been able to find a  
paper on the topic that doesn't dive head-first into complicated  
category theory (which I usually can't follow) ...

/aside


Rob Dockins

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

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


Re: [Haskell-cafe] Re: Functional programming for processing of largeraster images

2006-06-21 Thread Robert Dockins


On Jun 21, 2006, at 3:30 PM, Brian Hulley wrote:


Joel Reymont wrote:

I think the issue wasn't using functional programming for large image
processing, it was using Haskell. OCaml is notoriously fast and
strict. Haskell/GHC is... lazy.

Everyone knows that laziness is supposed to be a virtue. In practice,
though, I'm one of the people who either can't wrap their heads
around it or just find themselves having to fight it from the start.


Perhaps laziness is more foundational, in that you can write

 if2 c x y = if c then x else y


[snip some conversation...]


For those who haven't seen this already, here is a presentation by  
Simon PJ in which he discusses his views on laziness (among other  
things).


http://research.microsoft.com/~simonpj/papers/haskell-retrospective/ 
HaskellRetrospective.pdf



Takeaway point about laziness: Laziness keeps you honest by not  
allowing you to slip in side effects.


Bonus takeaway: read Wadler's papers :-)



Rob Dockins

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

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


Re: [Haskell-cafe] Computing lazy and strict list operations at the same time

2006-06-19 Thread Robert Dockins


On Jun 19, 2006, at 11:24 AM, C Rodrigues wrote:

Here's a puzzle I haven't been able to solve.  Is it possible to  
write the initlast function?


There are functions init and last that take constant stack  
space and traverse the list at most once.  You can think of  
traversing the list as deconstructing all the (:) [] constructors  
in list.


init (x:xs) = init' x xs
 where init' x (y:ys) = x:init' y ys
   init' _ [] = []

last (x:xs) = last' x xs
 where last' _ (y:ys) = last' y ys
   last' x [] = x

Now, is there a way to write initlast :: [a] - ([a], a) that  
returns the result of init and the result of last, takes constant  
stack space, and traverses the list only once?  Calling reverse  
traverses the list again.  I couldn't think of a way to do it, but  
I couldn't figure out why it would be impossible.



initlast :: [a] - ([a],a)
initlast (x:xs) = f x xs id
where
  f x (y:ys) g = f y ys (g . (x:))
  f x [] g = (g [],x)



Its within the letter, if maybe not the spirit of the rules.  The  
accumulated function could arguably be considered to be traversing  
the list again.  FYI, the technique is a fairly well known one for  
overcoming the quadratic behavior of repeated (++).



Rob Dockins

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

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


Re: [Haskell-cafe] Computing lazy and strict list operations at the same time

2006-06-19 Thread Robert Dockins


On Jun 19, 2006, at 12:50 PM, Duncan Coutts wrote:


On Mon, 2006-06-19 at 17:03 +0100, Jon Fairbairn wrote:

On 2006-06-19 at 15:24- C Rodrigues wrote:
Here's a puzzle I haven't been able to solve.  Is it possible to  
write the

initlast function?

There are functions init and last that take constant stack  
space and
traverse the list at most once.  You can think of traversing the  
list as

deconstructing all the (:) [] constructors in list.

init (x:xs) = init' x xs
  where init' x (y:ys) = x:init' y ys
init' _ [] = []

last (x:xs) = last' x xs
  where last' _ (y:ys) = last' y ys
last' x [] = x

Now, is there a way to write initlast :: [a] - ([a], a) that  
returns the
result of init and the result of last, takes constant stack  
space, and
traverses the list only once?  Calling reverse traverses the list  
again.  I
couldn't think of a way to do it, but I couldn't figure out why  
it would be

impossible.



il [] = error foo
il [x] = ([], x)
il (x:xs) = cof x (il xs)
where cof x ~(a,b) = (x:a, b)
--  !



From a quick test, it looks like none of our suggested solutions

actually work in constant space.



main = interact $ \s -
  case il s of
(xs, x) - let l = length xs
   in l `seq` show (l,x)

using ghc:
ghc -O foo.hs -o foo
./foo +RTS -M10m -RTS  50mb.data

using runhugs:
runhugs foo.hs  50mb.data

in both cases and for each of the three solutions we've suggested the
prog runs out of heap space where the spec asked for constant heap  
use.



Actually, the OP asked for constant stack space, which is quite  
different and much easier to achieve.




So what's wrong? In my test I was trying to follow my advice that we
should consume the init before consuming the last element. Was that
wrong? Is there another way of consuming the result of initlast that
will work in constant space?



That is, nonetheless, an interesting question.



Note that by changing discarding the x we do get constant space use:
main = interact $ \s -
  case il s of
(xs, x) - let l = length xs
   in l `seq` show l  -- rather than 'show (l,x)'

Why does holding onto 'x' retain 'xs' (or the initial input or some
other structure with linear space use)?

Duncan



Rob Dockins

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

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


  1   2   3   >