Re: [Haskell-cafe] type class question

2007-05-22 Thread Stefan Holdermans

Tim,


If I have a type class for conversion to a type X:

class XType a where
toX   :: a - X


[...]


instance XType String where toX  = ...

results in:

Illegal instance declaration for `XType String'
(The instance type must be of form (T a b c)
 where T is not a synonym, and a,b,c are distinct type
variables)
In the instance declaration for `XType String'


In addition to Derek's pointer, you could also consider extending the  
class definition:


  class XType a where
toX :: a   - X
listToX :: [a] - X
listToX =  ... -- some default definition for listToX

Of course, it depends on your type X whether a suitable default  
definition for listToX can be given. Assuming that it can, you can  
now, as before, have


  instance XType Int where toX  = ...
  instance XType Double where toX  = ...
  instance XType Tuple where toX  = ...

but also

  instance XType Char where
toX c = ...  -- your toX implementation for Char
listToX s = ...  -- your toX implementation for String

This 'trick' is used in the standard libraries to accommodate a Show  
instance for String, for instance.


Cheers,

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


Re: [Haskell-cafe] Editor OT: streamofconciousness

2007-05-22 Thread Jules Bean

John Meacham wrote:


It is somewhat depressing that immutable pre-packaged macros[1] and the
simple brute-force inclusion of separate tools[2] into the editor are
hailed as innovation, when new innovations, whether they are simple
refinements of old ideas[3], excercises in orthoginality[4], or truely
new research[5] are left to the wayside. But such is the power of the
bullet point.

John

[1] many (but not all) refactoring features i have seen.


This is a little harsh.

The refactoring features I've seen (in Eclipse) are more than macros; 
they are semantically aware. That is, they understand the scoping and 
typing of the language and they can distinguish between 'a' in an inner 
scope and 'a' in an outer scope, so they they can do a safe rename. Then 
can also distinguish between List (the class imported from 
my.cool.package) and List (the class imported from java.main.package) 
and do a safe multi-file rename so you have a true 'atomic' class 
renaming ability.


These things go well beyond syntactic macros. It is often stated that 
Java has such powerful IDEs because it's such a tedious language to edit 
without them, and I have some sympathy for that line of argument, but I 
would love to have local definition floating and project-global rename 
and so on in my haskell editor. I know people are working on this stuff.


Jules


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


Re: [Haskell-cafe] List algorithm

2007-05-22 Thread Matthew Brecknell
Mark T.B. Carroll:
 algMemo n m = last memo
 where
   memo = [[]] : map helper [1 .. m]
   helper m' = [ x : xs | x - [1 .. min m' n], xs - memo !! (m' - x) ]

This made me wonder whether it's safe to access an array while it's
still under construction:

 import Data.Array.IArray
 
 algArr n m = memo ! m where
   memo :: Array Int [[Int]]
   memo = listArray (0,m) $ [[]] : map helper [1..m]
   helper i = [ x:xs | x - [1..min i n], xs - memo ! (i-x) ]

This seems to work, but presumably only because it's a boxed array, and
the construction makes no circular references.

However, I'm doubtful that memoisation is really beneficial in this
function. I think it only gains a constant-factor speedup, but loses the
ability to work in constant space.

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


Re: [Haskell-cafe] List algorithm

2007-05-22 Thread Jules Bean

Matthew Brecknell wrote:

This seems to work, but presumably only because it's a boxed array, and
the construction makes no circular references.



Yes, AIUI the boxed arrays are strict in indices but lazy in values. 
Therefore they can be used for this kind of memoization trick as long as 
you're access the elements in 'some sensible order' (that is the 
calculation dependencies are well-ordered).

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


Re: [Haskell-cafe] Scope of type variables in associated types

2007-05-22 Thread Bertram Felgenhauer
Matthew Brecknell wrote:
 Bertram Felgenhauer:
  How does
  
class F a where
data B a :: *
data E a :: *
wrap :: B a - E a
unwrap :: E a - B a
  
  sound? 'B a' would represent the 'b' in your previous attempt,
  
class F a b | a - b where
...
  
 
 I'm with Simon in thinking that this code is suspicious.

It wasn't my code Simon was replying to.

 For any given call to wrap or unwrap, how is the compiler supposed
 to determine which instance to use, given that a cannot be uniquely
 determined from the type of the function?

As far as my limited understanding goes this should work, because we
are using an associated *data* type here. This means we can't have
instances saying 'type B a = Int', we have to use either a newtype
or a data declaration for that. As a side effect, the compiler can
determine 'a' from 'B a'.

This wouldn't be possible for associated type synonyms, but those
aren't completely implemented yet anyway (again, as far as I know).

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


Re: [Haskell-cafe] Editor

2007-05-22 Thread Paul Drummond

On 5/21/07, Michael T. Richter [EMAIL PROTECTED] wrote:


Code like makeRandomValueST :: StdGen - (MyType, StdGen) (which,
incidentally, was far easier to copy from in Gedit than GVim to paste into
this message) ...



Really?

To copy that line of code in vim you could do:

v%y

assuming the cursor is in the right place (at the start of the code) and if
it isn't it's easy in vim to get it there!

Of course, in Windows you must have guioptions=a in your config so that
all yanks go directly to the Windows clipboard (which should really be in
there by default but it isn't).

Vim is extremely powerful, but I understand that the steep learning curve is
a problem for many.  As a developer, I would recommend taking the time to
learn advanced features of any editor (whether emacs, vim, or whatever).  I
presume most developers on this list use regular expressions to navigate
their code despite the relatively steep learning curve, correct?

BTW:  Hello everyone - first post!  I planned to wait to introduce myself as
a Haskell newbie when I came up with my few questions but as a Vim lover I
couldn't resist posting about this!

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


[Haskell-cafe] Re: Editor

2007-05-22 Thread apfelmus
Jules Bean wrote:
 Michael T. Richter wrote:
1. A real GUI environment that takes into account some of the HID
   advances made in the past 30 years.  (Emacs and Vim don't count,
   in other words.)
 
 Both emacs and vim take into account many of the HID advances made in
 the past 30 years.

I can't know whether that's the case, but the fact that virtually all
commands are invoked with the keyboard clashes with HID research reported at

   http://www.asktog.com/TOI/toi06KeyboardVMouse1.html

It adresses the question whether selecting commands in menus with the
mouse or accessing them via keyboard shortcuts is faster. The answer is:

 * Test subjects consistently report that keyboarding is faster than
mousing.
  * The stopwatch consistently proves mousing is faster than
keyboarding.

Regards,
apfelmus

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


Re: [Haskell-cafe] List algorithm

2007-05-22 Thread Steffen Mazanek

Thank you for your responses.

My algorithm that needs the described function performs
so horribily bad that I understand now the need for CNF :-)

The idea was to write a CYK-style parser for an arbitrary
context-free grammar without transformation to CNF.
To compute derivations for a span of length i
I wanted to iterate over all productions p, counting
the number n of Nonterminals at the right-hand side of p,
computing all lists with n numbers whose sum is i and
split the span accordingly. It works, however, the strings
have to be very, very short *g*

Ciao and Thx,
Steffen

2007/5/22, Jules Bean [EMAIL PROTECTED]:


Matthew Brecknell wrote:
 This seems to work, but presumably only because it's a boxed array, and
 the construction makes no circular references.


Yes, AIUI the boxed arrays are strict in indices but lazy in values.
Therefore they can be used for this kind of memoization trick as long as
you're access the elements in 'some sensible order' (that is the
calculation dependencies are well-ordered).
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe





--
Dipl.-Inform. Steffen Mazanek
Institut für Softwaretechnologie
Fakultät Informatik

Universität der Bundeswehr München
85577 Neubiberg

Tel: +49 (0)89 6004-2505
Fax: +49 (0)89 6004-4447

E-Mail: [EMAIL PROTECTED]
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Inaugural London HUG meeting; attendee list suggestion

2007-05-22 Thread Bayley, Alistair
Tomorrow evening's London Haskell User Group meeting has a reasonable
list of attendees (inferred from the comments):
 
http://www.londonhug.net/2007/04/26/announcement-first-meeting-of-the-lo
ndon-haskell-user-group/

I think it'd be a good idea to do what the BCS-SPA does, and maintain a
wiki-page where attendees can add/remove themselves e.g.
  http://bcs-spa.org/cgi-bin/view/SPA/MakingSenseOfInformalInformation
  (scroll down to bottom of page, above map)
This gives a current picture of who's planning to attend, which might be
useful if you want to catch up with particular people.

Should we start something here, perhaps?
 
http://www.haskell.org/haskellwiki/London_Haskell_User_Group/Events/2007
0426

Alistair
*
Confidentiality Note: The information contained in this message,
and any attachments, may contain confidential and/or privileged
material. It is intended solely for the person(s) or entity to
which it is addressed. Any review, retransmission, dissemination,
or taking of any action in reliance upon this information by
persons or entities other than the intended recipient(s) is
prohibited. If you received this in error, please contact the
sender and delete the material from any computer.
*
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Editor

2007-05-22 Thread Jules Bean

apfelmus wrote:

I can't know whether that's the case, but the fact that virtually all
commands are invoked with the keyboard clashes with HID research reported at

   http://www.asktog.com/TOI/toi06KeyboardVMouse1.html

It adresses the question whether selecting commands in menus with the
mouse or accessing them via keyboard shortcuts is faster. The answer is:

 * Test subjects consistently report that keyboarding is faster than
mousing.
  * The stopwatch consistently proves mousing is faster than
keyboarding.



The research there is reported as hearsay, it is not referenced 
research, so I can't check their methods.


Despite the implicit claim that my brain must be lying to me and causing 
amnesia I'm unaware of, I would dispute the claims there. I suspect 
there might well be a large body of users (even 'most') for which it's 
true. However 'most' people are not fast typists.


I'm sure that I can quite reliably hit the command editor keybindings I 
use many, many times faster than if I had to select them from a menu.


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


[Haskell-cafe] RE: [Haskell] Inaugural London HUG meeting; attendee list suggestion

2007-05-22 Thread Bayley, Alistair
[this time to the list :-]

  Should we start something here, perhaps?
  

http://www.haskell.org/haskellwiki/London_Haskell_User_Group/Events/2007
0426
 
 Sounds a plausible idea, but shouldn't it be 20070523?
 
 Jeremy

Yeah... sorry, I totally fished that date out of a body cavity. I think
it was the date of the original blog post about the meeting. Corrected
URL:
 
http://www.haskell.org/haskellwiki/London_Haskell_User_Group/Events/2007
053

Is that a good way to label the event, though? If it needs to change
dates then the URL changes, which isn't so good. An alternative might be
a sequence number e.g.:
 
http://www.haskell.org/haskellwiki/London_Haskell_User_Group/Events/LHUG
-1

Alistair
*
Confidentiality Note: The information contained in this message,
and any attachments, may contain confidential and/or privileged
material. It is intended solely for the person(s) or entity to
which it is addressed. Any review, retransmission, dissemination,
or taking of any action in reliance upon this information by
persons or entities other than the intended recipient(s) is
prohibited. If you received this in error, please contact the
sender and delete the material from any computer.
*
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Editor

2007-05-22 Thread apfelmus
Jules Bean wrote:
 apfelmus wrote:
 I can't know whether that's the case, but the fact that virtually all
 commands are invoked with the keyboard clashes with HID research
 reported at

http://www.asktog.com/TOI/toi06KeyboardVMouse1.html

 It adresses the question whether selecting commands in menus with the
 mouse or accessing them via keyboard shortcuts is faster. The answer is:

  * Test subjects consistently report that keyboarding is faster than
 mousing.
   * The stopwatch consistently proves mousing is faster than
 keyboarding.
 
 
 The research there is reported as hearsay, it is not referenced
 research, so I can't check their methods.

Well, hearsay is probably not the right word but the selection of tasks
on which the conclusions are based is indeed vital yet missing. In

   http://www.asktog.com/SunWorldColumns/S02KeyboardVMouse3.html

, he reports on an actual experiment in response to a comment. It can be
debated (no use of advanced cursor positioning like M-f or M-b?), but
for the task at hand (replace all '|' by 'e' in a text by hand) the
mouse seems superior. Of course, a find/replace command performs much
better, so a keybinding for that would be worth it because it makes the
computer perform the task.

But in any case, this research can easily be reproduced at home! Of
course, nobody (include me) does :)

 Despite the implicit claim that my brain must be lying to me and causing
 amnesia I'm unaware of, I would dispute the claims there. I suspect
 there might well be a large body of users (even 'most') for which it's
 true. However 'most' people are not fast typists.

(I think amnesia is not a good choice of words. It's more like the
well-known effect from a quotation of A. Einstein Put your hand on a
hot stove for a minute, and it seems like an hour. Sit with a pretty
girl for an hour, and it seems like a minute. THAT'S relativity.)

 I'm sure that I can quite reliably hit the command editor keybindings I
 use many, many times faster than if I had to select them from a menu.

Note that the claimed time-consuming part is not to actually press the
keybinding, but to chose and remember which one to press.

Being sure and verified experimentally are two different things. The
question cannot be decided by arguments or by stating opions, only the
stopwatch can answer it. In a sense, the basic statement is that the
human's internal stopwatch is unreliable.

Regards,
apfelmus

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


Re: [Haskell-cafe] Scope of type variables in associated types

2007-05-22 Thread Matthew Sackman
Matthew Brecknell [EMAIL PROTECTED] wrote:
 Bertram Felgenhauer:
  How does
  
class F a where
data B a :: *
data E a :: *
wrap :: B a - E a
unwrap :: E a - B a
  
 For any given call to wrap or unwrap, how is the compiler supposed
 to determine which instance to use, given that a cannot be uniquely
 determined from the type of the function?

If it can't be uniquely determined then it blows up, as always. As far
as my understanding of type classes goes, for any call to a function in
a type class, the compiler must be able to determine a single instance
to call. So if all we know is that we have a B a then all we can do is
hope there's an instance F a.

 The same question also applies
 to Matthew's original formulation using functional dependencies:
 
  class G a b | a - b where
  data E a :: *
  wrap :: b - E a
  unwrap :: E a - b

Well here you certainly have less information, but you can still
determine the instance - in both wrap and unwrap you have an E a which
means the compiler will be able to work out some constraints on a.
There's also a b so it can also check that the fundep is respected, or
incorporate the extra information into its decision making process.

Note that both the above do type check and compile, and I have working
instances of the latter:

class CellBuilder c t n | c - t n where
data Cell c :: *
makeCell :: t - (MVar (Cell n)) - Cell c
unpackCell :: Cell c - (t, (MVar (Cell n)))

instance CellBuilder (Cons t n) t n where
data Cell (Cons t n) = CellCons t (MVar (Cell n))
makeCell v mvar = CellCons v mvar
unpackCell (CellCons v mvar) = (v, mvar)

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


RE: [Haskell-cafe] Re: Editor

2007-05-22 Thread Bayley, Alistair
  I'm sure that I can quite reliably hit the command editor 
 keybindings I
  use many, many times faster than if I had to select them 
 from a menu.
 
 Note that the claimed time-consuming part is not to actually press the
 keybinding, but to chose and remember which one to press.

Yes... except that for a lot of people, programmers especially, a lot of
key bindings have become part of your motor memory, and so you can
probably hit the common ones quite quickly without having to stop to
think about which combination of keys to press. Cut/copy/paste are good
examples of this, I think.

Alistair
*
Confidentiality Note: The information contained in this message,
and any attachments, may contain confidential and/or privileged
material. It is intended solely for the person(s) or entity to
which it is addressed. Any review, retransmission, dissemination,
or taking of any action in reliance upon this information by
persons or entities other than the intended recipient(s) is
prohibited. If you received this in error, please contact the
sender and delete the material from any computer.
*
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Editor

2007-05-22 Thread Donald Bruce Stewart
Alistair_Bayley:
   I'm sure that I can quite reliably hit the command editor 
  keybindings I
   use many, many times faster than if I had to select them 
  from a menu.
  
  Note that the claimed time-consuming part is not to actually press the
  keybinding, but to chose and remember which one to press.
 
 Yes... except that for a lot of people, programmers especially, a lot of
 key bindings have become part of your motor memory, and so you can
 probably hit the common ones quite quickly without having to stop to
 think about which combination of keys to press. Cut/copy/paste are good
 examples of this, I think.

Exactly, this is why my shell, window manager, mp3 player, web browser,
and editor all use hjkl to navigate :-)

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


Re: [Haskell-cafe] Re: Editor

2007-05-22 Thread Michael T. Richter
On Tue, 2007-22-05 at 10:19 +0200, apfelmus wrote:

 I can't know whether that's the case, but the fact that virtually all
 commands are invoked with the keyboard clashes with HID research reported at
 
http://www.asktog.com/TOI/toi06KeyboardVMouse1.html
 
 It adresses the question whether selecting commands in menus with the
 mouse or accessing them via keyboard shortcuts is faster. The answer is:
 
  * Test subjects consistently report that keyboarding is faster than
 mousing.
   * The stopwatch consistently proves mousing is faster than
 keyboarding.


You beat me to the punch.  And to exactly the same URL, in fact.

I see strong parallels between the insistence that keyboarding is faster
than mousing and the insistence that manual memory management is faster
than automated memory management.

-- 
Michael T. Richter [EMAIL PROTECTED] (GoogleTalk:
[EMAIL PROTECTED])
In his errors a man is true to type. Observe the errors and you will
know the man. (孔夫子)


signature.asc
Description: This is a digitally signed message part
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Editor

2007-05-22 Thread Jules Bean

Michael T. Richter wrote:

On Tue, 2007-22-05 at 10:19 +0200, apfelmus wrote:

I can't know whether that's the case, but the fact that virtually all
commands are invoked with the keyboard clashes with HID research reported at

   http://www.asktog.com/TOI/toi06KeyboardVMouse1.html

It adresses the question whether selecting commands in menus with the
mouse or accessing them via keyboard shortcuts is faster. The answer is:

 * Test subjects consistently report that keyboarding is faster than
mousing.
  * The stopwatch consistently proves mousing is faster than
keyboarding.


You beat me to the punch.  And to exactly the same URL, in fact.

I see strong parallels between the insistence that keyboarding is faster 
than mousing and the insistence that manual memory management is faster 
than automated memory management.





Why not abandon the keyboard, then, and have all your alphanumeric keys 
neatly lined up in menus? Or perhaps click on a picture of a keyboard? ;)


Assuming you wouldn't find the above more convenient, you concede then 
that some things are faster with the keys than the mouse. So it really 
is a question of degree. The mouse excels at tasks like 'select a 
particular large but illdefined (unstructured) chunk of text' : it's a 
very natural gesture. However as a programmer I am often working with 
much more structured text, and operations like 'move forward one 
sub-expression' or 'parenthesise the next two sub-expressions' tilt the 
balance back in favour of the keyboards.


The mouse is an analog input device and it excels at analog operations 
and exploratory ones (poking around menus and tabbed dialogs). The 
keyboard is a digital device and it excels at concise precision, such as 
'let-float the next 4 definitions up one level'.


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


Re: [Haskell-cafe] List algorithm

2007-05-22 Thread Henning Thielemann

On Mon, 21 May 2007, Steffen Mazanek wrote:

 is there an efficient algorithm that takes two positive numbers n and m and
 that computes all lists l of numbers 0x=n such that sum l = m?

 For instance
 alg 5 1 = [[1]]
 alg 5 2 = [[1,1],[2]]
 alg 5 3 = [[1,1,1],[1,2],[2,1],[3]]
 ...

http://darcs.haskell.org/htam/src/Combinatorics/Partitions.hs

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


Re: [Haskell-cafe] List algorithm

2007-05-22 Thread Henning Thielemann

On Mon, 21 May 2007, Mark T.B. Carroll wrote:

 Steffen Mazanek [EMAIL PROTECTED] writes:

  alg 5 1 = [[1]]
  alg 5 2 = [[1,1],[2]]
  alg 5 3 = [[1,1,1],[1,2],[2,1],[3]]

 Would this be better?

 alg n m =
 case signum m of
   -1 - []
   0 - [[]]
   1 - [ x : xs | x - [1..n], xs - alg n (m - x) ]

This would produce compiler warnings. What about:

case compare m 0 of
  GT -
  EQ -
  LT -

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


Re: [Haskell-cafe] efficient and/or lazy partitions of a multiset

2007-05-22 Thread Henning Thielemann

On Mon, 21 May 2007, Greg Meredith wrote:

 HC-er's,

 Find below some simple-minded code from a naive Haskeller for generating all
 partitions of a multiset about which i have two questions.

 mSplit :: [a] - [([a], [a])]
 mSplit [x] = [([x],[])]

What about [] ?

See
  http://www.haskell.org/haskellwiki/Base_cases_and_identities

 mSplit (x:xs) = (zip (map (x:) lxs) rxs)
   ++ (zip lxs (map (x:) rxs))
   where (lxs,rxs) = unzip (mSplit xs)

1. Is there a clever way to reduce the horrid complexity of the naive
approach?
2. How lazy is this code? Is there a lazier way?

The code looks good. Maybe instead of doing
  zip ... ++ zip ...
 you should interleave the generated lists. This will probably reduce the
need of constructing elements if only a prefix of (mSplit xs) is
requested.

mSplitLazy [] = [([],[])]
mSplitLazy (x:xs) =
  let (lxs,rxs) = unzip (mSplitLazy xs)
  lys = zip (map (x:) lxs) rxs
  rys = zip lxs (map (x:) rxs)
  in  concat (zipWith (\a b - [a,b]) lys rys)

If you are also after elegance - how about the List monad?

mSplitMonad [] = [([],[])]
mSplitMonad (x:xs) =
   do (lxs,rxs) - mSplitMonad xs
  [(x:lxs,rxs), (lxs,x:rxs)]

Or more condensed:

mSplitFoldr =
   foldr
 (\x - concatMap (\(lxs,rxs) - [(x:lxs,rxs), (lxs,x:rxs)]))
 [([],[])]
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] type class question

2007-05-22 Thread Henning Thielemann

On Tue, 22 May 2007, Tim Docker wrote:

 I think this must almost be a FAQ, or at least a PAQ (Previously AQ)...

I think it too, thus I added your case to the Wiki:
 http://www.haskell.org/haskellwiki/List_instance
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] haskell wiki indexing

2007-05-22 Thread Vincent Kraeutler
as was pointed out on the programming reddit [1], crawling of the
haskell wiki is forbidden, since http://www.haskell.org/robots.txt contains

User-agent: *
Disallow: /haskellwiki/

and indeed, a google search gives the old wiki
http://www.google.ch/search?q=haskell+wiki
i.e.
http://haskell.org/hawiki/FrontPage
rather than
http://haskell.org/haskellwiki/Haskell

in other words, it seems like the most relevant search engines do not
index the haskell wiki. i have reported this on #haskell about a week
ago[2], and this setting was acknowledged to be a measure deliberately
taken to curb excessive load from spiders crawling the wiki. i still
believe this a highly harmful stance, and just to make sure that whoever
may feel concerned is at least aware of the problem, i am now
cross-posting to this list as well.

kind regards,
v.

[1] http://programming.reddit.com/info/1qzjx/comments/c1r3ok
[2] http://tuukka.iki.fi/tmp/haskell-2007-05-16.html









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


Re: [Haskell-cafe] List algorithm

2007-05-22 Thread Mark T.B. Carroll
Matthew Brecknell [EMAIL PROTECTED] writes:
(snip)
 This seems to work, but presumably only because it's a boxed array, and
 the construction makes no circular references.

Yes. (-:

 However, I'm doubtful that memoisation is really beneficial in this
 function. I think it only gains a constant-factor speedup, but loses the
 ability to work in constant space.

I don't know. The memoised version certainly calls the bit with the list
comprehension fewer times. I'd have to think about it more.

-- Mark

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


Re: [Haskell-cafe] Ann: Emping 0.2

2007-05-22 Thread Hans van Thiel
On Mon, 2007-05-21 at 14:06 -0700, Scott Cruzen wrote: 
 Is Emping an implementation of C4.5 or something new?
No, it's new. The reduction algorithm is not based on a measure and is
not a search either. It's a construction of predicate combinations,
starting with singletons, that are not contradictory to known facts. The
third step, following hypothesis and then falsification, is verification
with observed rules. 
The complexity appears to be  quadratic to the original rule length and
also to the number of original rules, but I have yet to prove this. I
believe I have proved that the algorithm produces the complete and
shortest disjunctive normal form of a logical rule table. 
The white paper 'Deriving heuristic rules from facts'
http://j-van-thiel.speedlinq.nl/dwnl/EmpingWP.pdf (21 pages) discusses
the theory from examples, and an earlier wp (also available on the web
site) uses some first order predicate logic and set theory.

Version 0.2 also shows logical dependencies in the reduced rules and
this is just a search in the original rules and in the poset of
reductions. So this is not new in a theoretical sense, though I believe
no other implementation has ever considered such dependencies. 

Regards,

Hans van Thiel
 
 * Hans van Thiel [EMAIL PROTECTED] [070521 05:45]:
  Hello All,
  
  Version 0.2 of Emping, a utility to derive heuristic rules from a table
  of nominal data, is available. In addition to a reduced normal form
  in .csv format, which can be read by Open Office Calc, it now also
  displays observed implications and equivalences in the reduced rules (if
  present) and ambiguities in original rules (if present). 
  A bug in the response to a user typing error has been fixed and some
  code has been simplified, compared to 0.1. An online user guide is at:
  http://j-van-thiel.speedlinq.nl/emp/empug.html and the Cabal package can
  be downloaded from there, or from the HackageDB.
  
  Thanks,
  
  Hans van Thiel
  
  
  ___
  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] List algorithm

2007-05-22 Thread haskell
Matthew Brecknell wrote:
 Mark T.B. Carroll:
 algMemo n m = last memo
 where
   memo = [[]] : map helper [1 .. m]
   helper m' = [ x : xs | x - [1 .. min m' n], xs - memo !! (m' - x) ]

 This made me wonder whether it's safe to access an array while it's
 still under construction:

 import Data.Array.IArray

 algArr n m = memo ! m where
   memo :: Array Int [[Int]]
   memo = listArray (0,m) $ [[]] : map helper [1..m]
   helper i = [ x:xs | x - [1..min i n], xs - memo ! (i-x) ]

 This seems to work, but presumably only because it's a boxed array, and
 the construction makes no circular references.

 However, I'm doubtful that memoisation is really beneficial in this
 function. I think it only gains a constant-factor speedup, but loses the
 ability to work in constant space.


If you call this function many times you may want to keep (some of) the memo
table between calls:

m'store,m'store'temp :: Int
m'store = 4
m'store'temp = 10

m'arr :: Array Int [[Int]]
m'arr = listArray (0,m'store) $ [[]] : map helper [1..m'store]
  where helper i = [ x:xs | x - [1..i], xs - m'arr ! (i-x) ]

alg :: Int - Int - [[Int]]
alg _n m | m  0 = error alg: Cannot total to negative
alg n m = if m  m'store'temp
then [ x : xs | x - [1..min n m], xs - alg n (m-x) ]
else let cached = if m = m'store then m'arr ! m
  else m'temp ! m
 in if n = m then cached
  else filter (all (=n)) cached
  where bound = (succ m'store, min m m'store'temp)
m'temp :: Array Int [[Int]]
m'temp = listArray bound (map help (range bound))
help i = [ x : xs | x - [1..min n i], xs - alg i (m-i) ]

The above uses some space for the global memo table m'arr and for a given call
may use additional space for m'temp.  For m larger than m'store'temp it will not
allocate a memo table will run slower (but without consuming so much space).

*Main alg 6 5
[[1,1,1,1,1],[1,1,1,2],[1,1,2,1],[1,1,3],[1,2,1,1],[1,2,2],[1,3,1],[1,4],[2,1,1,1],[2,1,2],[2,2,1],[2,3],[3,1,1],[3,2],[4,1],[5]]

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


Re: [Haskell-cafe] haskell wiki indexing

2007-05-22 Thread Henning Thielemann

On Tue, 22 May 2007, Vincent Kraeutler wrote:

 as was pointed out on the programming reddit [1], crawling of the
 haskell wiki is forbidden, since http://www.haskell.org/robots.txt contains

 User-agent: *
 Disallow: /haskellwiki/

 and indeed, a google search gives the old wiki
 http://www.google.ch/search?q=haskell+wiki
 i.e.
 http://haskell.org/hawiki/FrontPage
 rather than
 http://haskell.org/haskellwiki/Haskell

This also applies to Haskell mailing lists as I mentioned recently:
 http://www.haskell.org/pipermail/haskell-cafe/2007-April/025006.html
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Editor

2007-05-22 Thread Malcolm Wallace
   * Test subjects consistently report that keyboarding is faster than
  mousing.
* The stopwatch consistently proves mousing is faster than
  keyboarding.

Even if it is empirically true that mousing is wall-clock faster than
keyboarding, one has to ask the question why users feel internally that
keyboarding wins.  Perhaps it is because using the mouse requires a
cognitive switch from editing the document, to a physical hand-eye
co-ordination task, and back again?  The mental effort of switching
might be harder work than keeping your focus on the document at all
times, and therefore switching _feels_ as if it must be slower.

Of course this assumes that the person is sufficiently skilled at typing
on a keyboard that they do not need to look at it, and hence their eye
can stay with the cursor in a window on the screen.

Perhaps you can find and move your mouse using only peripheral vision,
but even so, the first cognitive task you need to accomplish is to find
the mouse pointer on screen, which is invariably in a different place
from the text cursor, and so drags your attention from one focus to
another.

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


[Haskell-cafe] Re: List algorithm

2007-05-22 Thread Christian Maeder
Henning Thielemann schrieb:
 On Mon, 21 May 2007, Steffen Mazanek wrote:
 
 is there an efficient algorithm that takes two positive numbers n and m and
 that computes all lists l of numbers 0x=n such that sum l = m?

 For instance
 alg 5 1 = [[1]]
 alg 5 2 = [[1,1],[2]]
 alg 5 3 = [[1,1,1],[1,2],[2,1],[3]]
 ...
 
 http://darcs.haskell.org/htam/src/Combinatorics/Partitions.hs
 
 alg  =  flip partitionsDec

*Combinatorics.Partitions partitionsDec 5 3
[[3],[2,1],[1,1,1]]

so [1,2] is missing. And for these partitions I've also the attached module.

*Partition parts 3
[3,2 1,1 1 1]

Christian
module Partition where

{- | a strictly increasing list of pairs where the second components are
the frequencies -}
newtype Part = Part [(Int, Int)] deriving (Eq, Ord)

instance Show Part where
show (Part l) = showIntList $ partToList $ reverse l 

showIntList :: [Int] - String
showIntList = unwords . map show

partToList :: [(Int, Int)] - [Int]
partToList = concatMap ( \ (v, f) - replicate f v)

infixr 5 :
(:) :: (Int, Int) - [(Int, Int)] - [(Int, Int)]
p@(_, c) : l = if c == 0 then l else p : l

extendPart :: [(Int, Int)] - [[(Int, Int)]]
extendPart l = case l of
[] - []
(v, c) : r - 
if v == 1 then 
case r of 
  [] - [l]
  (v2, c2) : s - 
  let i = v2 - 1
  (di, mi) = divMod (c + v2) i 
  in l : extendPart (
(if mi == 0 then id else ((mi, 1) :))
 $ (i, di) : (v2, c2 - 1) : s)
else l : extendPart (
  (if v == 2 then [(1, 2)]
   else [(1, 1), (v - 1, 1)]) ++ (v, c - 1) : r)

parts :: Int - [Part]
parts n = if n  0 then [] else if n == 0 then [Part []] else 
   map Part $ extendPart [(n, 1)]
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Editor

2007-05-22 Thread Michael T. Richter
On Tue, 2007-22-05 at 13:48 +0100, Malcolm Wallace wrote:

* Test subjects consistently report that keyboarding is faster than
   mousing.
 * The stopwatch consistently proves mousing is faster than
   keyboarding.
 
 Even if it is empirically true that mousing is wall-clock faster than
 keyboarding, one has to ask the question why users feel internally that
 keyboarding wins.  Perhaps it is because using the mouse requires a
 cognitive switch from editing the document, to a physical hand-eye
 co-ordination task, and back again?  The mental effort of switching
 might be harder work than keeping your focus on the document at all
 times, and therefore switching _feels_ as if it must be slower.
 
 Of course this assumes that the person is sufficiently skilled at typing
 on a keyboard that they do not need to look at it, and hence their eye
 can stay with the cursor in a window on the screen.
 
 Perhaps you can find and move your mouse using only peripheral vision,
 but even so, the first cognitive task you need to accomplish is to find
 the mouse pointer on screen, which is invariably in a different place
 from the text cursor, and so drags your attention from one focus to
 another.


All this talk about efficiency while editing text would make me
believe that most of my time spend writing software is typing.  Yet,
oddly enough, I find that the typing is the least of my tasks.  Most of
my work is done in my head, on whiteboards or on scraps of paper long
before my fingers stroke a keyboard.

-- 
Michael T. Richter [EMAIL PROTECTED] (GoogleTalk:
[EMAIL PROTECTED])
When debugging, novices insert corrective code; experts remove defective
code. (Richard Pattis)


signature.asc
Description: This is a digitally signed message part
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] haskell wiki indexing

2007-05-22 Thread Claus Reinke

as was pointed out on the programming reddit [1], crawling of the
haskell wiki is forbidden, since http://www.haskell.org/robots.txt contains

User-agent: *
Disallow: /haskellwiki/


i agree that having the wiki searchable would be preferred,
but was told that there were performance issues. even giving
Googlebot a wider range than other spiders won't help if, as
the irc page suggests, some of those faulty bots pretend to be
Googlebot..


This also applies to Haskell mailing lists as I mentioned recently:
http://www.haskell.org/pipermail/haskell-cafe/2007-April/025006.html


ah, yes, sorry. there was an ongoing offlist discussion at the
time, following an earlier thread on ghc-users. Simon M has
since changed robots.txt to the above, which *does* permit
indexing of the pipermail archives, as long as google can find
them. that still doesn't mean that they'll show up first in google's
ranking system. for instance, if you google for

   'ghc manuals online'

(that's the subject for that earlier thread i mentioned), you'll
get mail-archive and nabble first, but the haskell.org archives
are there as well now, as you can see by googling for

   'ghc manuals online inurl:pipermail'

also, the standard test of googling for 'site:haskell.org' looks
a lot healthier these days. and googling for

   'inurl:ghc/docs/latest LANGUAGE pragma'

gives me two relevant answers (not the most specific sub-page).

so the situation for mailing lists and online docs seems to have
improved, but there is still the wiki indexing/rogue bot issue,
and lots of fine tuning (together with watching the logs to spot
any issues arising out of relaxing those restrictions). perhaps
someone on this list would be willing to volunteer to look into
those robots/indexing issues on haskell.org?-)

claus


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


Re: [Haskell-cafe] Re: Editor

2007-05-22 Thread Ketil Malde
On Tue, 2007-05-22 at 10:19 +0200, apfelmus wrote:

 http://www.asktog.com/TOI/toi06KeyboardVMouse1.html
 
 It adresses the question whether selecting commands in menus with the
 mouse or accessing them via keyboard shortcuts is faster. The answer is:
 
  * Test subjects consistently report that keyboarding is faster than
 mousing.
   * The stopwatch consistently proves mousing is faster than
 keyboarding.

Interesting!  I did a quick test doing search and replace using the
keyboard and the menus in Emacs.  It takes me about six seconds with the
keyboard, and closer to ten using the menus.  (The first time, it took
thirty as I spent time to locate the correct menu options :-)

But I agree with the report that using the mouse *feels* a lot slower. 
Quoting the report: It takes two seconds to decide upon which
special-function key to press. Deciding among abstract symbols is a
high-level cognitive function.

I'm not so sure I agree, using the mouse feels way more abrupt and
intrusive.  I can do M-x repl TAB str TAB foo RET bar RET with my eyes
closed¹, but to use the mouse, I need to locate the mouse with my hand,
locate the mouse cursor, locate the menu, etc etc.

Maybe that'd change if I used the mouse more?

-k

¹ I can, but probably shouldn't.  I just tried, but didn't realize focus
was not in Emacs but my mail client - which consequently promptly did a
bunch of unpredictable things to my draft.

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


Re: [Haskell-cafe] haskell wiki indexing

2007-05-22 Thread Duncan Coutts
On Tue, 2007-05-22 at 14:40 +0100, Claus Reinke wrote:

 so the situation for mailing lists and online docs seems to have
 improved, but there is still the wiki indexing/rogue bot issue,
 and lots of fine tuning (together with watching the logs to spot
 any issues arising out of relaxing those restrictions). perhaps
 someone on this list would be willing to volunteer to look into
 those robots/indexing issues on haskell.org?-)

The main problem, and the reason for the original (temporary!) measure
was bots indexing all possible diffs between old versions of wiki pages.
URLs like:

http://haskell.org/haskellwiki/?title=Quicksortdiff=9608oldid=9607

For pages with long histories this O(n^2) number of requests starts to
get quite large and the wiki engine does not seem well optimised for
getting arbitrary diffs. So we ended up with bots holding open many http
server connections. They were not actually causing much server cpu load
or generating much traffic but once the number of nearly hung
connections got up to the http child process limit then we are
effectively in a DOS situation.

So if we can ban bots from the page histories or turn them off for the
bot user agents or something then we might have a cure. Perhaps we just
need to upgrade our media wiki software or find out how other sites
using this software deal with the same issue of bots reading page
histories.

Duncan

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


Re: [Haskell-cafe] haskell wiki indexing

2007-05-22 Thread Henning Thielemann

On Tue, 22 May 2007, Duncan Coutts wrote:

 So if we can ban bots from the page histories or turn them off for the
 bot user agents or something then we might have a cure. Perhaps we just
 need to upgrade our media wiki software or find out how other sites
 using this software deal with the same issue of bots reading page
 histories.

What about adding the nofollow flag in the meta tags of the history
pages?
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] haskell wiki indexing

2007-05-22 Thread Duncan Coutts
On Tue, 2007-05-22 at 16:26 +0200, Henning Thielemann wrote:
 On Tue, 22 May 2007, Duncan Coutts wrote:
 
  So if we can ban bots from the page histories or turn them off for the
  bot user agents or something then we might have a cure. Perhaps we just
  need to upgrade our media wiki software or find out how other sites
  using this software deal with the same issue of bots reading page
  histories.
 
 What about adding the nofollow flag in the meta tags of the history
 pages?

Sounds like a good idea. If someone can do that then great.

Duncan

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


RE: [Haskell-cafe] haskell wiki indexing

2007-05-22 Thread Bayley, Alistair
   So if we can ban bots from the page histories or turn 
 them off for the
   bot user agents or something then we might have a cure. 
 Perhaps we just
   need to upgrade our media wiki software or find out how 
 other sites
   using this software deal with the same issue of bots reading page
   histories.
  
  What about adding the nofollow flag in the meta tags of 
 the history
  pages?
 
 Sounds like a good idea. If someone can do that then great.


Apparently other people have used URL rewriting to keep robots of
subsets of the wiki pages:
  http://www.gustavus.edu/gts/webservices/2006/08/14/robots-in-the-wiki/
 
http://codex.gallery2.org/Gallery2:How_to_keep_robots_off_CPU_intensive_
pages

Is that an option for our installation?

Alistair
*
Confidentiality Note: The information contained in this message,
and any attachments, may contain confidential and/or privileged
material. It is intended solely for the person(s) or entity to
which it is addressed. Any review, retransmission, dissemination,
or taking of any action in reliance upon this information by
persons or entities other than the intended recipient(s) is
prohibited. If you received this in error, please contact the
sender and delete the material from any computer.
*
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] haskell wiki indexing

2007-05-22 Thread Robin Green
On Tue, 22 May 2007 15:05:48 +0100
Duncan Coutts [EMAIL PROTECTED] wrote:

 On Tue, 2007-05-22 at 14:40 +0100, Claus Reinke wrote:
 
  so the situation for mailing lists and online docs seems to have
  improved, but there is still the wiki indexing/rogue bot issue,
  and lots of fine tuning (together with watching the logs to spot
  any issues arising out of relaxing those restrictions). perhaps
  someone on this list would be willing to volunteer to look into
  those robots/indexing issues on haskell.org?-)
 
 The main problem, and the reason for the original (temporary!) measure
 was bots indexing all possible diffs between old versions of wiki
 pages. URLs like:
 
 http://haskell.org/haskellwiki/?title=Quicksortdiff=9608oldid=9607
 
 For pages with long histories this O(n^2) number of requests starts to
 get quite large and the wiki engine does not seem well optimised for
 getting arbitrary diffs. So we ended up with bots holding open many
 http server connections. They were not actually causing much server
 cpu load or generating much traffic but once the number of nearly hung
 connections got up to the http child process limit then we are
 effectively in a DOS situation.
 
 So if we can ban bots from the page histories or turn them off for the
 bot user agents or something then we might have a cure. Perhaps we
 just need to upgrade our media wiki software or find out how other
 sites using this software deal with the same issue of bots reading
 page histories.

http://en.wikipedia.org/robots.txt

Wikipedia uses URLs starting with /w/ for dynamic pages (well, all
pages are dynamic in a sense, but you know what I mean I hope.) And
then puts /w/ in robots.txt.
-- 
Robin
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] haskell wiki indexing

2007-05-22 Thread Claus Reinke
The wiki could be configured to use /haskellwiki/index.php?.. urls for 
diffs (I believe this can be done by changing $wgScript). Then 
robots.txt could be changed to

 Disallow: /haskellwiki/index.php
Which bans robots from everything except normal pages.


that sounds like the most promising approach to me (meta tags 
for history pages already have noindex,nofollow; so that didn't 
help, it seems? also, fewer robots look at meta tags than at

robots.txt).

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


Re: [Haskell-cafe] How do I insert an element in HaXml?

2007-05-22 Thread Malcolm Wallace
Jeremy Shaw [EMAIL PROTECTED] wrote:

 Another example is sorting the children.

  sortedChildren match =
mkElem match [ sortBy ((=) `on` tagName) . children ]
  `o` tag match
where tagName (CElem (Elem name _ _ _)) = name

or maybe, to use the labelling combinators rather than the underlying
representation:

  sortedChildren match =
mkElem match [ const keep `oo`
   sortBy ((=) `on` fst) . tagged children ]
  `o` tag match

Of course, one outstanding problem is that the
mkElem e [ ... ] `o` tag e
trick does not preserve attributes from the matched element.

 Then I can express the filter like this:
   chip (editElem (mkElem newElement [] `union` children)
`when` (keep / tag b))
 
 But, I don't see an obvious way to implement 'editElem' using the
 existing combinators. 

Yes, this is definitely difficult without 'editElem'.  Not only do you
need to preserve the element's attributes, but also its tag name.  It
would be nice to be able to bind some result of a combinator expression
to a variable name, then use the bound name elsewhere in the expression,
but unfortunately this is not how things work in HaXml.  Maybe if
CFilters were monadic? ... it is an idea I have played with but never
settled on.

 I am not sure if it is because there is a hole in my understanding, or
 if there is an hole in what the combinators can express.

I am sympathetic to the idea that there could be an unfilled hole in the
design space, in particular that there may be simpler primitive
combinators from which to build more powerful and comprehensive editing
facilities.

 If I introduce a new (poorly named) primitive:
 
   editElem :: CFilter - CFilter
   editElem f c@(CElem (Elem name as _)) = [ CElem (Elem name as (f c)) ]

This is remarkably similar to the definition of 'chip', except that it
applies the filter to the element itself, rather than to its children.
Hence, a name suggestion based on this relationship could be 'inplace'.
It definitely looks useful certainly more primitive than 'chip', and
I'll add it to HaXml, unless you can think of an even better combinator!

 On the other hand, 'chip' can be implemented in terms of 'editElem':
  chip' = editElem children

Strictly speaking, it would be
chip' f = editElem (f `o` children)
You can't eta-reduce `o` as if it were normal composition!

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


[Haskell-cafe] Re: efficient and/or lazy partitions of a multiset

2007-05-22 Thread Greg Meredith

Henning,

In your reply, you made a number of interesting suggestions. You could also
have written

mSplitC :: [a] - [([a], [a])] -- C for comprehension

mSplitC [] = [([],[])]
mSplitC [x] = [([x],[])]
mSplitC (x:xs) = concat [ [(x:l,r),(l,x:r)] | (l,r) - mSplitC xs ]

which Matthias Radestock suggested to me.

Note that if you only supply the empty multiset case, then you end up with
duplicates.

mSplitCD :: [a] - [([a], [a])]
mSplitCD [] = [([],[])]
mSplitCD (x:xs)  = concat [[(x:l,r),(l,x:r)] | (l,r) - mSplitCD xs]

*Zoup mSplitCD [1,2,3]
[([1,2,3],[]),([2,3],[1]),([1,3],[2]),([3],[1,2]),([1,2],[3]),([2],[1,3]),([1],[2,3]),([],[1,2,3])]

*Zoup mSplitC [1,2,3]
[([1,2,3],[]),([2,3],[1]),([1,3],[2]),([3],[1,2])]
*Zoup

Is there anyway to peer under the hood to see the code being generated? i
notice, for example, that the original concat/zip-based implementation
occasionally comes in quite a bit faster that the comprehension based
example.

Best wishes,

--greg


On 5/21/07, Greg Meredith [EMAIL PROTECTED] wrote:


HC-er's,

Find below some simple-minded code from a naive Haskeller for generating
all partitions of a multiset about which i have two questions.

mSplit :: [a] - [([a], [a])]
mSplit [x] = [([x],[])]
mSplit (x:xs) = (zip (map (x:) lxs) rxs)
  ++ (zip lxs (map (x:) rxs))
  where (lxs,rxs) = unzip (mSplit xs)

   1. Is there a clever way to reduce the horrid complexity of the
   naive approach?
   2. How lazy is this code? Is there a lazier way?

i ask this in the context of checking statements of the form \phi * \psi
|= e_1 * ... * e_n where

   - [| \phi * \psi |] = { a \in U : a === b_1 * b_2, b_1 \in [| \phi
   |], b_2 \in [| \psi |] }
   - === is some congruence generated from a set of relations

A nice implementation for checking such statements will iterate through
the partitions, generating them as needed, checking subconditions and
stopping at the first one that works (possibly saving remainder for a rainy
day when the client of the check decides that wasn't the partition they
meant).

Best wishes,

--greg

--
L.G. Meredith
Managing Partner
Biosimilarity LLC
505 N 72nd St
Seattle, WA 98103

+1 206.650.3740

http://biosimilarity.blogspot.com





--
L.G. Meredith
Managing Partner
Biosimilarity LLC
505 N 72nd St
Seattle, WA 98103

+1 206.650.3740

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


Re: [Haskell-cafe] Re: Editor

2007-05-22 Thread Albert Y. C. Lai
This recent development of the thread leads me to these conclusions and 
conjectures.


* If you want to demonstrate the mouse to be faster than the keyboard, 
you can contrive an experiment to do so. Example: Randomize occurences 
of X's in a text, ask to replace them by Y's, but make sure there is no 
find-replace command or wizard to help.


* If you want to demonstrate the keyboard to be faster than the mouse, 
you can contrive an experiment to do so. Example: Ask to crack open your 
favourite Haskell textbook and enter it into the computer.


Some of us raise that speed is not the only concern. Indeed, cognitive 
switch may be more taxing on the worker. However, going on a limb, I'm 
going to wager that:


* If you want to demonstrate the mouse to be less taxing than the 
keyboard, you can probably contrive an experiment to do so.


* If you want to demonstrate the keyboard to be less taxing than the 
mouse, you can probably contrive an experiment to do so.


The keyboard-mouse duality (duelity?) doesn't end here. Some of us 
explains that keyboarding has become part of our motor skill, and 
mousing has not quite. So I ask, are there also people who are the opposite?


One year I went to COMDEX Canada (in Toronto) and saw a live demo of 
Photoshop or something. The demonstrator was amazing. He clicked through 
the menu system faster than I could watch! He performed long sequences 
of back-to-back menu mousing at a sustained speed paralleling that of my 
keyboarding. You may say aha, Photoshop, analog! but no, in his demo 
analog operations were the minority, the majority was on the discrete 
menus - I do mean it when I say long sequences of back-to-back menu 
mousing. A possible objection would be that he practiced on his demo. 
But I do invite you to observe someone who uses Photoshop or the like 
professionally; you may see a level of mouse-fu you never thought possible.


But all this musing on HCI and HCI research may all be just talking wind 
because:


Michael T. Richter wrote:
All this talk about efficiency while editing text would make me 
believe that most of my time spend writing software is typing.  Yet, 
oddly enough, I find that the typing is the *least* of my tasks.  Most 
of my work is done in my head, on whiteboards or on scraps of paper long 
before my fingers stroke a keyboard.


Conventional wisdom would say: Then the priority is on improving the 
head, the whiteboard, and the paper. Give secondary priority to HCI and 
IDE dreams.


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


Re: [Haskell-cafe] Editor OT: streamofconciousness

2007-05-22 Thread Chaddaï Fouché

While I strongly disagree with you on the fact that refactoring is
just big macros (well it is, simply they're macros which operate more
on structured code than on structured text, ie they're aware of the
semantic of the language on which they're operating, and I don't know
you but I don't code macro like that in less than a few days/weeks
(/months ?)... Let's say _really_ big macros and settle at that), I
thank you for introducing me to acme. It seems really interesting, and
with the acme-sac project I can use it on my OS.
So thanks.

(Oh and if you saw things your coworker called refactoring and you
would have done as well with a one-line macro in emacs (or even a
standard command), it's just that you're right to consider
refactoring as a buzzword, but it's not only that)

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


Re: [Haskell-cafe] global variables

2007-05-22 Thread Isaac Dupree
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Isaac Dupree wrote:
 Maybe some sort of ISOLATE, DON'T_OPTIMIZE (but CAF), or
 USED_AS_GLOBAL_VARIABLE pragma instead of just the insufficient NOINLINE
 would be a good first step... if successful it would remove the
 occasional need for -fno-cse for a whole module in GHC, at least.

ISOLATE, DON'T_OPTIMIZE are actually bad names for the whole effect,
which requires persistent CAF semantics.  An implementation that doesn't
make top-level definitions be CAFs, or even one that is willing to
garbage-collect them when memory is tight such that they need
recalculation later, would need a special case for global variables to
make them work.

i.e. I'm not sure if there exists a reasonable pragma while the code
still uses unsafePerformIO.

Hmm

How about

so,
{-# NOINLINE var #-}
var :: IORef Int
var = unsafePerformIO (newIORef 3)

- --

var :: IORef Int
var = {-# EVALUATE_THIS_TEXT_ONLY_ONCE #-} (unsafePerformIO (newIORef 3))

to capture the desired semantics: text-based uniqueness, no duplication,
no sharing of the IORefs (sharing the pure contents is fine), and no
need to actually evaluate it any times at all. {-#
EVALUATE_THIS_TEXT_ONLY_ONCE #-} is syntactically like a (special)
function.  Clearly it is an impossible demand for polymorphic things, so
the compiler could complain (at least a warning) if the (var :: IORef
Int) line was left off, for example. I guess it would also complain
about non-type(class) argument dependencies too such as (f x =
(unsafePerformIO (newIORef (x::Int))) )...

Food for thought :-)


Isaac
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGU02YHgcxvIWYTTURAoCaAKCkDH7Pd7JbNt0TmNig9j7ujiUV9ACZAevI
QOjdmMbrPfVrKBafZshCh7c=
=9/5v
-END PGP SIGNATURE-
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Editor

2007-05-22 Thread Ashley Yakeley

Michael T. Richter wrote:
I have a dream.  It's not a little dream.  It's a big dream.  I have a 
dream that someday I can find a UNIX/Linux text editor for Haskell 
hacking (and possibly two or three hundred other programming languages, 
although that's optional) that can give me all of the following:


   1. A real GUI environment that takes into account some of the HID
  advances made in the past 30 years.  (Emacs and Vim don't count,
  in other words.)


I don't suppose you're familiar with the Dylan programming language, or 
more to the point, have looked at the IDE that Apple included in their 
original implementation of the language (around 1993 or so)? 
Characteristic of Apple of that time, the UI was both highly innovative 
and a joy to use. It was based around browsers, where each browser had 
a subject (such as a project, module, definition etc.) and an aspect 
(such as contents of, errors in, references to, direct methods 
of etc.). Browsers could be linked so that the selection in one browser 
became the subject in another. This made it very easy to navigate your 
project.


All code was stored in a database rather than as text files, and 
individual code definitions were separate objects in the browsers rather 
than pieces of text in a big file.


Info w/ screenshots: http://osteele.com/museum/apple-dylan
http://wiki.opendylan.org/wiki/view.dsp?title=Apple%20Dylan
Needless to say, this goes in rather the opposite UI direction to the 
Ctrl-M Ctrl-Meta-Z esc :edit qx approach to editors that some people 
prefer.


Dylan's not a bad language, and there are open source implementations 
available for Gnu/Linux. But if you want to check out Apple's IDE, 
you'll really need a 68K Mac, as the PPC version is very buggy and I 
don't think the 68K version will run in PPC.


--
Ashley Yakeley
Seattle, WA

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


Re: [Haskell-cafe] Re: Editor

2007-05-22 Thread Gabor Greif

Am 23.05.2007 um 00:20 schrieb Ashley Yakeley:

I don't suppose you're familiar with the Dylan programming  
language, or more to the point, have looked at the IDE that Apple  
included in their original implementation of the language (around  
1993 or so)? Characteristic of Apple of that time, the UI was both  
highly innovative and a joy to use. It was based around browsers,  
where each browser had a subject (such as a project, module,  
definition etc.) and an aspect (such as contents of, errors  
in, references to, direct methods of etc.). Browsers could be  
linked so that the selection in one browser became the subject in  
another. This made it very easy to navigate your project.


All code was stored in a database rather than as text files, and  
individual code definitions were separate objects in the browsers  
rather than pieces of text in a big file.


Info w/ screenshots: http://osteele.com/museum/apple-dylan
http://wiki.opendylan.org/wiki/view.dsp?title=Apple%20Dylan
Needless to say, this goes in rather the opposite UI direction to  
the Ctrl-M Ctrl-Meta-Z esc :edit qx approach to editors that  
some people prefer.


Dylan's not a bad language, and there are open source  
implementations available for Gnu/Linux. But if you want to check  
out Apple's IDE, you'll really need a 68K Mac, as the PPC version  
is very buggy and I don't think the 68K version will run in PPC.


Michael's blog:

http://snakeratpig.blogspot.com/2007/02/road-to-haskell.html

Dylan and Haskell are very similar in the multiple-dispatch (a  
haskeller would call that

pattern matching on several arguments) respect.

Cheers,

Gabor

PS: Btw, the Apple Dylan IDE works well on PPC if you apply a patch  
that was issued by

Digitool shortly after the initial port of the IDE to PPC.

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


Re: [Haskell-cafe] Re: Editor (OT: keyboard mouse / one device + my 2 cents)

2007-05-22 Thread Marc Weber
I did think about this topic many times.
My conclusion: We need some other kind of interface (keyboard and mouse
at the same time which would speed up your workflow very often,
especially when doing some kind of graphics where you have to enter some
text)..

One solution I did find is http://www.combimouse.com/index.htm .. 
But I have'nt been able to afford this nice idea to test it.
Another is one is http://www.jazzmutant.com/lemur_overview.php 
(too expensive to be buyed by me in the near future ..  )
Another example is the iPod ...
  stop
 move the finger to on the surface to scroll 
  play   (or something like this), I don't have one.

I totally agree that you can't say the one is faster than the other way.

When I'm faster using the keyboard (Perhaps I only think I am? :)
  finding logout (find as you type firefox), because I can even reach
  the link if it's not in the visible area.
  
  Finding directories I use often (because I don't have to look at many
  files/ directories I'm not interested in.. Perhaps my visual
  perception is not as fast as the perception of others?)
  Compare using property editors with code (find property visibility in
  either alphabetical or sectioned)..

  Finding menus on Windows (Because the move very often if you install
  new software, work on foreign computers etc).. But that's why tools
  like lounchy (windows) exist.

  Moving Windows using wmii (althoug nifty windows for Win is very nice
  as well, but you have to take off your hands..)

  scrolling (using page down/ space / return application dependend)

  tying gimptab instead of (where the hell is that icon? Oh no it
  looks different because I have a newer version ..)

  using special commands such as goto previous cursor position...

  Opening files using glob patterns in vim (having mapped **/*
  (eg :e **/*some.hstabcr )
  Opening most recent files having them listed in a buffer where I can
  use search. (compare this to File - Open - c:\MyProjects\. )

I'm faster using the mouse:
  navigating in directories I don't know..
  (But often I use something like find | less to get an overview )

  ... 

My friend is using the mouse most often. He is very fast. But Sometimes
you can't get as fast as using the keyboard because you have to wait
till the application pops up the window so that you see where to
click. (Example: A lot of windows Dialogs (Eg change the PATH variable))

Anyway it would be really interesting to use 2 mice for some tasks.
Then you can use one for scrolling and the other to click and drag.
Or you can put both on menu items (where you think they'll pop up such
as File - save) and click in sequence. But this havily depends on the
application. Eg MS office (Not the new redisigned gui) is horrible
because it does always hide the menu items I'm looking for (perhaps
because I'm not using them very often or I don't know yet how to switch
them off). Another horrible examples are tex editors wether you can click
on buttons inserting \alpha \beta etc. Then you are switching between
keyboard and mouse all the time.

If the mouse is faster why does eclipse have so much opportunities to
filter lists/ trees ?

But I do know that I really like tools such as xfig / inckscape because
they have the keyboard shortcuts I need (select tools/ view ..)
And you are definitely faster using them using the mouse to select the
tool and moving back. But of course you have to learn them.

When watching my sister or my father using the mouse very often they
simply click on the small triangle (step up / down) in scrollbars
instead of PageUp/Down. But this is a kind of usage pattern which can be
[ ] 
step  page left   move
left
improved by using scrolling (middle mouse button click), maximizing the
window (Windows often doesn't permit this, eg when customizing menus or
shortcuts (Visual Studio/ Word etc) before scrolling down a
list etc..

I hope I didn't talk too much and that you have found some stuff  in this
post you didn't know already ...

Marc

PS: How would mouse gestures compare to keyboard shortcuts concerning
the 2 seconds amnesia having been mentioned in article some posts ago?
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: [Haskell] boilerplate boilerplate

2007-05-22 Thread Jacques Carette

Personally I would like
{-# OPTIONS -fglasgow-exts -fgenerics -}
module Blog.Types where

family Usual = (Eq, Ord, Read, Show, Typeable)

data BlogEntry = Entry EpochSeconds Name Email Title Body  deriving Usual
newtype Name = Name String   deriving Usual
newtype Title = Title String deriving Usual
newtype Body = Body String deriving Usual

Of course, if you're doing that, you might as well change those last 3 
lines with

newtype-schema NamedString = NamedString String deriving Usual
instantiate NamedString with Name, Title, Body

To me, that is very clear.  Syntax-wise, I am sure things can be 
improved (but I rather like 'family', 'foo-schema' and 'instantiate', 
but not really the 'with').


Jacques

Alex Jacobson wrote:
Consider this module for a blog entry that I will want to put in 
various generic collections that require Ord


  {-# OPTIONS -fglasgow-exts #-}
  module Blog.Types where
  import Data.Typeable
  import Data.Generics

  data BlogEntry = Entry EpochSeconds Name Email Title Body 
   deriving (Eq,Ord,Read,Show,Typeable)


  newtype Name = Name String deriving (Eq,Ord,Read,Show,Typeable)
  newtype Title = Title String deriving (Eq,Ord,Read,Show,Typeable)
  newtype Body = Body String deriving (Eq,Ord,Read,Show,Typeable)


It seems really unnecessarily verbose.  Having to add the OPTION 
header AND import Data.Typeable and Data.Generics just to derive 
Typeable is a beat-down.  It is even more of a beat-down to have to 
add a deriving clause for every newtype to make this all work nicely.  
Is there a way to make all types automatically derive everything 
unless there is an explicit instance declaration otherwise?


  {-# OPTIONS -fglasgow-exts -fgenerics -fderiving#-}
  module Blog.Types where

  data BlogEntry = Entry EpochSeconds Name Email Title Body 
  newtype Name = Name String   newtype Title = Title String   newtype 
Body = Body String

Isn't that much nicer?

-Alex-


___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell

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


RE: [Haskell-cafe] type class question

2007-05-22 Thread Tim Docker
Thanks for this - I only wonder if the page title List Instance would
have
suggested that this was a solution to me problem - I can't think of a
better
name however: Lists as type class instances perhaps?


-Original Message-
From: Henning Thielemann [mailto:[EMAIL PROTECTED] 
Sent: Tuesday, 22 May 2007 10:11 PM
To: Tim Docker
Cc: haskell-cafe@haskell.org
Subject: Re: [Haskell-cafe] type class question


On Tue, 22 May 2007, Tim Docker wrote:

 I think this must almost be a FAQ, or at least a PAQ (Previously
AQ)...

I think it too, thus I added your case to the Wiki:
 http://www.haskell.org/haskellwiki/List_instance
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Currying: The Rationale

2007-05-22 Thread PR Stanley

Hi
What is the rationale behind currying? is it for breaking subroutines 
into pure one-to-one mappings? If f x y = f x - a function which 
takes y for argument then does that mean that the second function 
already has value x, as it were, built into it?
The syntax in Haskell is perfectly lucid and almost intuitive; unlike 
the underlying theory which is a bit ...

top marks for the least jargoned answer.
Many thanks in advance,
Paul

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


Re: [Haskell-cafe] Currying: The Rationale

2007-05-22 Thread Philippa Cowderoy
On Wed, 23 May 2007, PR Stanley wrote:

 Hi
 What is the rationale behind currying? is it for breaking subroutines into
 pure one-to-one mappings?

We don't have 'subroutines' as such, but otherwise yes. Also, it gives us 
partial application - we don't have to apply all the parameters at once, 
and we can do interesting and useful things by applying only some to get a 
new function.

 If f x y = f x - a function which takes y for
 argument then does that mean that the second function already has value x, as
 it were, built into it?

Yep, though I can't make sense of what your syntax is supposed to mean.

-- 
[EMAIL PROTECTED]

Society does not owe people jobs.
Society owes it to itself to find people jobs.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Currying: The Rationale

2007-05-22 Thread PR Stanley



 Hi
 What is the rationale behind currying? is it for breaking subroutines into
 pure one-to-one mappings?

We don't have 'subroutines' as such, but otherwise yes. Also, it gives us
partial application - we don't have to apply all the parameters at once,
and we can do interesting and useful things by applying only some to get a
new function.

 If f x y = f x - a function which takes y for
 argument then does that mean that the second function already has 
value x, as

 it were, built into it?

Yep, though I can't make sense of what your syntax is supposed to mean.
I shouldn't take it too literally. It's just to illustrate the point 
that f x returns another function with x already in it and y passed 
as argument.
Could you perhaps demonstrate how you can apply parts of curried 
functions in other functions in Haskell?

Thanks,
Paul


--
[EMAIL PROTECTED]

Society does not owe people jobs.
Society owes it to itself to find people jobs.


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


Re: [Haskell-cafe] Currying: The Rationale

2007-05-22 Thread Brandon S. Allbery KF8NH


On May 22, 2007, at 22:35 , PR Stanley wrote:
Could you perhaps demonstrate how you can apply parts of curried  
functions in other functions in Haskell?


A trivial example:


Prelude map (+1) [1..10]
[2,3,4,5,6,7,8,9,10,11]


(Strictly speaking (+1) is a section, but that's just a syntactic  
special case of currying.)


More usefully, the same thing can be used in a State monad with the  
modify function:



Prelude Control.Monad.State runState (modify (+1)) 1
((),2)


While this is again a trivial example, you can use modify with a  
curried function or a section in more complicated examples to modify  
the state in place.


--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED]
system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED]
electrical and computer engineering, carnegie mellon universityKF8NH


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


Re: [Haskell-cafe] Currying: The Rationale

2007-05-22 Thread Donald Bruce Stewart
prstanley:
 
  Hi
  What is the rationale behind currying? is it for breaking subroutines 
 into
  pure one-to-one mappings?
 
 We don't have 'subroutines' as such, but otherwise yes. Also, it gives us
 partial application - we don't have to apply all the parameters at once,
 and we can do interesting and useful things by applying only some to get a
 new function.
 
  If f x y = f x - a function which takes y for
  argument then does that mean that the second function already has 
 value x, as
  it were, built into it?
 
 Yep, though I can't make sense of what your syntax is supposed to mean.
 I shouldn't take it too literally. It's just to illustrate the point 
 that f x returns another function with x already in it and y passed 
 as argument.
 Could you perhaps demonstrate how you can apply parts of curried 
 functions in other functions in Haskell?

(^) applied to 2, produces a new function, we can map over a list:

Prelude let sq = (^2)
Prelude map sq [1..10]
[1,4,9,16,25,36,49,64,81,100]

or more explicitly:

Prelude let x `to` y = x ^ y
Prelude let sq x = x `to` 2
Prelude map sq [1..10]
[1,4,9,16,25,36,49,64,81,100]

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


Re: [Haskell-cafe] Re: Editor

2007-05-22 Thread brad clawsie
it should also be noted that there are rsi issues with switching
constantly between mouse and keyboard. moving to an environment that
focuses on textual input (mutt+emacs+elinks on top of screen on top of
xmonad) has allowed me to keep my hands in the ergonomic position
dictated by my keyboard. for people with extreme-ergo keyboards
(kinesis etc), keeping your fingers in position is important




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