Re: [Haskell-cafe] Small question

2007-08-11 Thread Stefan O'Rear
On Sat, Aug 11, 2007 at 12:06:23AM -0400, David Menendez wrote:
 On 8/10/07, Andrew Coppin [EMAIL PROTECTED] wrote:
 
  My program needs to make decisions based on a pair of boolean values.
  Encoding both values as a single algebraic data type means I have to
  keep taking it apart so I can work with it. I'm not sure how much time
  this wastes...
 
 Incidentally, there is an argument that many (perhaps most) use of
 Bool should instead be custom datatypes. That is, instead of:
 
 type FooBar = (Bool, Bool)
 
 one should instead do something like
 
 data Foo = Foo | AntiFoo
 data Bar = Baz | Bo
 type FooBar = (Foo, Bar)
 
 which makes it clearer what's going on and harder to confuse the two booleans.
 
 Of course, now you have to replace
 
 \(foo, bar) - if foo then ... else ...
 with
 \(foo, bar) - if foo == Foo then ... else ...
 or
 \(foo, bar) - case foo of { Foo - ...; Bar - ... }

 Actually, that raises an interesting question. Is there a performance
 difference between if foo == Foo ... and case Foo of ...? I think
 JHC's case-hoisting should be able to transform the former into the
 latter, but does it?

You don't need to go all the way to JHC[1] for this; GHC's case-of-case
transformation is perfectly adequate, as GHC itself will tell you:

[EMAIL PROTECTED]:/tmp$ ghc -c -ddump-simpl -O2 X.hs
...
X.moo :: X.Ay - GHC.Base.Int
...
X.moo =
  \ (x_a6D :: X.Ay) - case x_a6D of wild_Xq { X.Be - X.lit; X.Ce - X.lvl }
[EMAIL PROTECTED]:/tmp$ cat X.hs
module X where

data Ay = Be | Ce deriving(Eq)

moo x = if x == Be then 2 else (3::Int)
[EMAIL PROTECTED]:/tmp$ ghc -c -ddump-simpl-stats -O2 X.hs
 FloatOut stats: 
1 Lets floated to top level; 0 Lets floated elsewhere; from 4 Lambda groups
 FloatOut stats: 
0 Lets floated to top level; 0 Lets floated elsewhere; from 3 Lambda groups
 Grand total simplifier statistics 
Total ticks: 46

9 PreInlineUnconditionally
11 PostInlineUnconditionally
6 UnfoldingDone
1 RuleFired
1 ==#-case
9 BetaReduction
2 CaseOfCase---
7 KnownBranch
1 CaseMerge
11 SimplifierDone
[EMAIL PROTECTED]:/tmp$

Stefan

[1] GHC takes 2 hours to run a full two-stage bootstrap complete with
the entire standard library.  Jhc takes[2] at least 4 hours (I
didn't let it finish) to compile just the Prelude.

[2] 700MB working set, 384MiB primary store.  This makes a difference.


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


Re: [Haskell-cafe] Explaining monads

2007-08-11 Thread David Menendez
On 8/10/07, Ronald Guida [EMAIL PROTECTED] wrote:

 Kim-Ee Yeoh wrote:
   Monads are undoubtedly more pervasive, and that could be because there
   aren't as many arrow and comonad tutorials, atomic ones or otherwise.

 Moreover, Comonad isn't even in the standard libraries (Hoogle returns
 no results for it).

This is probably because no one has found a compelling use case for
comonadic-style programming in Haskell. There have been some
interesting papers, such as Comonadic functional attribute
evaluation by Uustalu and Vene, but nothing as compelling as Wadler's
Monads for functional programming.

 In my case, I have started to formulate my own idea for what a monad
 tutorial should be; I might attempt to write one, too.

Be sure to read sigpfe's You could have invented monads! and the Wadler paper.

http://sigfpe.blogspot.com/2006/08/you-could-have-invented-monads-and.html
http://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf

Most tutorials try to explain what a monad *is*, but these focus more
on why they're a useful way to organize code. In my experience, being
able to use a monad is more important than understanding the theory.

 Also, arrows are supposed to be more general than both monads and
 comonads.  If I could just figure out what each structure (functor,
 monad, comonad, arrow) is doing, and compare and contrast them, then I
 probably will have made leaps of understanding.

Arrows are more general than monads and comonads in the sense that you
can create an arrow corresponding to any particular monad and comonad,
but there are also arrows which correspond to neither.

Functors are more general than monads and comonads simply because
every monad and comonad is a functor with additional operations. (This
can be obscured by the fact that the Haskell Prelude doesn't define
Monad as a subclass of Functor.)
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Explaining monads

2007-08-11 Thread Donald Bruce Stewart
ronguida:
 
  Monads are undoubtedly more pervasive, and that could be because there
  aren't as many arrow and comonad tutorials, atomic ones or otherwise.
 
 Moreover, Comonad isn't even in the standard libraries (Hoogle returns
 no results for it).
 
 When I searched for tutorials on monads, I found lots of them.  In
 fact, I have heard that writing (yet another) monad tutorial is part
 of standard Haskell initiation.
 

Regarding the available tutorials, I've collected them under each
flavour here:

haskell.org/haskellwiki/Blog_articles/Monads 

Including 42 monad tutorials, 6 arrow tutorials, and 3 comonad
tutorials, and 0 on applicative functors.

The source for the `standard' (only) comonad library is available from
one of the sigfpe tutorials, but really should be on hackage.

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


[Haskell-cafe] zip3, zip4 ... - zipn?

2007-08-11 Thread Frank Buss
Is it possible to write a function like this:

zipn n list_1 list_2 list_3 ... list_n

which implements zip3 for n=3, zip4 for n=4 etc.? Looks like variable number
of arguments are possible, like printf shows, so a general zipn should be
possible, too. If it is possible, why there are functions like zip5 and not
just zipn?

-- 
Frank Buss, [EMAIL PROTECTED]
http://www.frank-buss.de, http://www.it4-systems.de

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


Re: [Haskell-cafe] Explaining monads

2007-08-11 Thread Kim-Ee Yeoh


Ronald Guida wrote:
 
 Here's my interpretation of the table:
 
 --
  Structure   | Subject  |  Action|  Verb  |  Result
  +--+++--
  function|  a   |  a-b  |  flip ($)  |  b
  Functor |  f a |  a-b  |  $   |  f b
  Applicative |  f a |  f (a-b)  |  flip *  |  f b
  Monad   |  m a |  a-m b|  =   |  m b
  Comonad |  w a |  w a-b|  =   |  w b
  Arrow   |  a b c   |  a c d | |  a b d
 --
 

This is the first time I've seen $. What a pleasing synonym for fmap. To
maintain a similar order of parameters, I think you'd want flip $ up
there.


Ronald Guida wrote:
 
 --
 Foo   a   = Foo { runFoo ::a } -- Functor
 State   s a   = State   { runState   :: s  - (a, s) } -- Monad
 Context c a   = Context { runContext :: (a, c) -  a } -- Comonad
 Thing   s a b = Thing   { runThing   :: (a, s) - (b, s) } -- Arrow???
 --
 

I believe there is a way to see all of the above as forms of generalized
application although not in the way presented here. (I thank Brian for
pointing to the possibility of a unified treatment in the first place.) 

A point in common among your run* functions is that you can always observe
the instance of type (a) in (m a :: Monad a). But monads are equipped with
(return :: a - m a), not (coreturn :: m a - a). Your 2nd table is more
about comonads, at least the coreturn aspect, than about whatever unity
you're hoping to achieve. There's more about coreturn here:
http://www.haskell.org/pipermail/haskell-cafe/2007-August/030153.html

So we need to explore generalized application without being too explicit
about unwrapping monads nor wrapping comonads. Why? Because being too
explicit invariably locks us into one particular instantiation and the
generalization goes poof! Think of all the otherwise rich and creative
papers written on the IO monad and its innards. 

The instances of monads I've seen are in themselves too sexy (probabilistic
modelling! digital circuit simulation! IO! concurrency!) that they end up
overwhelming the essence of monadism pregnant within. Better to start with
something boring. Like the Maybe monad.

Feck heh, The essence of monadism pregnant within. Another fine title for
another monad tutorial.

-- 
View this message in context: 
http://www.nabble.com/Explaining-monads-tf4244948.html#a12103564
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

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


Re: [Haskell-cafe] Haskell vs GC'd imperative languages, threading, parallelizeability (is that a word? :-D )

2007-08-11 Thread Andrew Coppin

Spencer Janssen wrote:

On Friday 10 August 2007 12:37:31 Andrew Coppin wrote:
  

Stefan O'Rear wrote:


Bool is 32 bits, but Don is using UArray.  UArray is not parametric in
the element type.
  

Would be nice if it *could* somehow be parametric... but I have
absolutely no idea how you'd do that. The transformation is self-evident
enough to a human, but how do you explain it to a machine?




Check out the various papers, slides, and talks on NDP/parrallel arrays.  
There's much discussion on schemes to efficiently pack data types into 
unboxed arrays.
  


NDP is like Christmas! So many boxes of goodies to open... but it takes 
so long to come around... :-(


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


Re: [Haskell-cafe] zip3, zip4 ... - zipn?

2007-08-11 Thread Joel Koerwer
Frank,

The return type of zipn would have to depend on the number of
arguments. If you are satisfied with all arguments having the same
type, then you can use transpose:

zipn list1 list2 .. listn  = transpose [list1, list2, .. listn]

Can we make a polyvariadic zipn that returns a [HList]? Seems like a
neat challenge, but I'm a bit pressed for time right now. I'm afraid
it would be pretty unwieldy.

I'm looking forward to seeing solutions though. :-)

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


Re: [Haskell-cafe] zip3, zip4 ... - zipn?

2007-08-11 Thread Hugh Perkins
I was looking for something like this too.

Note that Erlang can do this ;-)  but Erlang is probably not so
strongly typed, so it's easier to do?
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] howto install ghc-6.7.* ?

2007-08-11 Thread Marc A. Ziegert
i just don't get it.
please, can anybody explaim me how to do that?
i tried it the last few days with ghc-6.7.20070807, ghc-6.7.20070809, and 
ghc-6.7.20070810.
it always results in a broken library (without Prelude):

# ghc-pkg list
/usr/local/lib/ghc-6.7.20070810/package.conf:
{ghc-6.7.20070810}, rts-1.0

i did this on my gentoo-i386-box (pretty old, takes 1h for quick build, 3.5h 
without mk/build.mk):

T=20070810
tar xjf ghc-6.7.$T-src.tar.bz2 
tar xjf ghc-6.7.$T-src-extralibs.tar.bz2 
cd ghc-6.7.$T
(
#echo BuildFlavour = quick
#cat mk/build.mk.sample
echo HADDOCK_DOCS = YES
)  mk/build.mk
./configure  ( time nice -n 19 make all install )


those extralibs seem to be installed in
 /usr/local/lib/ghc-6.7.20070810/lib/
but registered in
 ghc-6.7.20070810/driver/package.conf.inplace
instead of
 /usr/local/lib/ghc-6.7.20070810/package.conf
.


- marc


pgpn4RY5OC2Kc.pgp
Description: PGP signature
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] arrow question HXT related

2007-08-11 Thread Andrea Rossato
Hi,

I think this is just a stupid arrow question. Still I cannot find
where my mistake is located.

Suppose I have a simple xml document I want to process with HXT:
root
  elem
   sub /
   risubtext/risub
  /elem
/root

After extracting elem I want to duplicate the children trees with
the arrow operator () and process them to get each sub element,
like I try in treMe2.

Below the example code. While I can get each sub element with tryMe
and tryMe1, tryMe2 will produce a []. Instead I want something like
tryMe3. I think I'm missing something stupid but right now I just feel
stupidly blind.

Thanks for your help,

Andrea


import Text.XML.HXT.Arrow

xml = rootelemsub /risubtext/risub/elem/root

tryMe = runLA arrow []
where arrow = constA xml  xread 
   
  deep (hasName elem)  getChildren 
   
  (hasName risub  getChildren  getText)

tryMe1 = runLA arrow []
where arrow = constA xml  xread 
   
  deep (hasName elem)  getChildren 
   
  (hasName sub  withDefault (getChildren  getText) 
ciao)

tryMe2 = runLA arrow []
where arrow = constA xml  xread 
   
  deep (hasName elem)  getChildren 
   
  (hasName sub  withDefault (getChildren  getText) 
ciao)
  
  (hasName risub  getChildren  getText)

tryMe3 = runLA arrow []
where arrow = constA xml  xread 
   
  constA first
  
  constA second

The output:

*test tryMe
[text]
*test tryMe1
[ciao]
*test tryMe2
[]
*test tryMe3
[(first,second)]
*test 
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Small question [new Wiki page up]

2007-08-11 Thread Andrew Coppin

Stefan O'Rear wrote:



Good idea!  Maybe it could be fit into the GHC Performance Resource
somehow?  (http://www.haskell.org/haskellwiki/Performance/GHC)
  

OK. But it'll probably contain a lot of guessing to start with... ;-)



Wiki pages can be fixed.  Private misunderstandings can't, at least not
anywhere near as easily.
  


A page now exists:

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

Everybody feel free to point and laugh. (Or, more helpfully, expand and 
correct!)


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


Re: [Haskell-cafe] arrow question HXT related

2007-08-11 Thread Andrea Rossato
On Sat, Aug 11, 2007 at 11:50:19AM +0200, Andrea Rossato wrote:
 Hi,
 
 I think this is just a stupid arrow question. Still I cannot find
 where my mistake is located.
 

well, it was not an arrow problem but a HXT problem. This new version
of tryMe2 does work as expected:

tryMe2 = runLA arrow []
where arrow = constA xml  xread 
   listA (
 deep (hasName elem)
  
 (deep (hasName sub)  withDefault (getChildren 
 getText) ciao)
 
 (deep (hasName risub)  getChildren  
getText)
)

Sorry for the noise.

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


[Haskell-cafe] Re: Language support for imperative code. Was: Re: monad subexpressions

2007-08-11 Thread apfelmus

Brian Hulley schrieb:

apfelmus wrote:

However, most genuinely imperative things are often just a building
block for a higher level functional model. The ByteString library is a
good example: the interface is purely functional, the internals are
explicit memory control. It's a bad idea to let the internal memory
control leak out and pollute an otherwise purely functional program with
IO-types.


Regarding the quote above, if the API must hide explicit memory control 
from the user the only way I can see of doing this would be to use 
(unsafePerformIO), which really is unsafe since Haskell relies on the 
fact that mutable operations can't escape from the IO monad in order to 
get away with not having to impose a value restriction as in ML.


Indeed, Data.ByteString makes heavy use of unsafePerformIO and
inlinePerformIO. This is safe since it's just used for efficient memory
access and (de-)allocation, the ByteStrings themselves are immutable.

If you don't use (unsafePerformIO), then the slightest need for mutable 
data structures pollutes the entire interface.


Well, any code that wants to mutate or read this data structure has to
announce so in the type signature. However, it's debatable whether
certain forms of mutation count as pollution. In fact, the simplest
mutation is just a function  s - s  . Haskell is throughly polluted
by such mutations:

  (3+) :: Int - Int
  ([1,2]++):: [Int] - [Int]
  insert x 3 :: Map String Int - Map String Int

Of course, from the purely functional point of view, this is hardly
perceived as mutation since the original value is not changed at all and
still available. In other words, the need to change a value doesn't
imply the need to discard (and thus mutate) the old one.

Mutable data structures in the sense of ephemeral (= not persistent = 
update in-place) data structure indeed do introduce the need to work in 
ST since the old version is - by definition - not available anymore. 
This may be the right thing to do when the data structure is inherently 
used in a single-threaded fashion. However, most used-to-be ephemeral 
data structures have very good persistent counterparts in Haskell. In 
the end, the type just reflects the inherent difficulty of reasoning 
about ephemeral data structures. And that's what the quoted paper 
illustrates: persistent data structures are much easier to deal with.



For example in the excellent paper you quoted

 N. Ramsey and J. Dias.
 An Applicative Control-Flow Graph Based on Huet's Zipper
 http://www.eecs.harvard.edu/~nr/pubs/zipcfg-abstract.html 
http://www.eecs.harvard.edu/%7Enr/pubs/zipcfg-abstract.html


the authors are pleased to have found an Applicative solution, and 
indeed their solution has many useful and instructive aspects. However 
on page 111, hidden away in the definition of their API function to 
create a label, is a call to (ref 0)  ;-) The equivalent 
implementation in Haskell would completely destroy all hope of using 
this in a pure context and force all use of the API into the IO monad.


I don't know enough ML or have the background to judge whether this  ref 
 is really necessary, but I doubt that it can't be designed away.



Haskell is designed so that any attempt at abstracting mutable

 local state will infect the entire program

Depends on local. In general, I think is a good thing. The type 
reflects how difficult your program really is, nothing more, nothing 
less. That's how it is: persistent data and prue functions are sooo much 
easier to reason about. Implicit side effects just sweep the difficulty 
under the carpet. (I imagine a tool that makes implicit side effects 
explicitly visible in the types of say C or ML programs. I guess that 
people would scream whole nights when seeing the output of this tool on 
their programs and thus discovering how complicated the code really is 
... Well, maybe not since they're used to it during debugging anyway.)


But if the state is really local, no infection of the entire program 
takes place! The best example is probably indeed the Haskell Graphics 
library. The are pure functions for constructing graphics


  over:: Graphic - Graphic - Graphic
  polygon :: [Point] - Graphic

and some IO-infected functions to draw those onto the screen

  drawInWindow :: Window - Graphic - IO ()

Now,  Graphic  may be implemented as an abstract data type and 
drawInWindow  does the workload of interpreting it. Or, and that's how 
HGL currently implementes it, it can be an IO-action that encodes how to 
draw it


  type Graphics = Draw ()
   ~= (Brush,Font,Pen) - IO ()

That is, every graphic is infested with IO but that doesn't spread to 
the API. (It does a bit with  selectBrush  but that can be corrected.)


 (modulo use of a highly dangerous function whose
semantics is entirely unclear, depending on the vagaries of evaluation 
strategy of the particular compiler)


(yes, unsafePerformIO clearly isn't for ephemeral data structures.)


For 

Re: [Haskell-cafe] How odd...

2007-08-11 Thread Jacques Carette

[Sorry for the long quote, but context is important]

Dan Piponi wrote:

It's fairly standard practice, when documenting functions of a complex
variable, to specify precisely which 'branch cuts' are being used.
Here's a quote from the Mathematica documentation describing their Log
function: Log[z] has a branch cut discontinuity in the complex z
plane running from  -infinity to 0.

  

With this interpretation, (-1)^(1/3) = 0.5 + sqrt(3)/2 * i.  If you go with
the real solution (-1) you might need to do so carefully in order to
preserve other useful properties of ^, like continuity.



You can guarantee this by making sure you make the right 'cuts'.
  


If only it were that simple.  Up until rather recently, it was not even 
known if there was a set of right cuts for ln and all the arc-trig 
functions that would work together properly.  See
`According to Abramowitz and Stegun or arccoth needn't be uncouth', by 
Corless, Jeffrey, Watt and Davenport, available from

http://citeseer.ist.psu.edu/corless00according.html
or
http://www.apmaths.uwo.ca/~djeffrey/Offprints/couth.pdf

This is by no means a solved problem.  For example, there is still no 
consensus as to where the branch cuts for the various versions of the 
LegendreQ function should go.


Jacques
http://www.apmaths.uwo.ca/%7Edjeffrey/Offprints/couth.pdf
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: zip3, zip4 ... - zipn?

2007-08-11 Thread apfelmus

Frank Buss schrieb:

Is it possible to write a function like this:

zipn n list_1 list_2 list_3 ... list_n

which implements zip3 for n=3, zip4 for n=4 etc.? Looks like variable number
of arguments are possible, like printf shows, so a general zipn should be
possible, too. If it is possible, why there are functions like zip5 and not
just zipn?


What type would this function have? It's not possible to formulate this 
type in Haskell98. The problem is that the number of arguments cannot be 
determined statically, i.e. it depends on the value of  n  at run-time. 
There are languages more freaky than Haskell (like Agda or Epigram ) 
that can do that (without dynamic typing, that is!), they are called 
dependently typed.


However, type-class hackery (or type synonym families once they're 
available in GHC) can be used to do something like that if you give the 
value of n at compile-time. I won't dwell into that, though.


Also, applicative functors can help

  GHCi :m +Control.Applicative
  GHCi (\x y z - x*(y+z)) $ ZipList [1,2,3]
* ZipList [-1,0,1] * ZipList [1,1,1]
  ZipList [0,2,6]
  GHCi

(the second command is a single line.)

Regards,
apfelmus

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


Re: [Haskell-cafe] zip3, zip4 ... - zipn?

2007-08-11 Thread Brent Yorgey
On 8/11/07, Frank Buss [EMAIL PROTECTED] wrote:

 Is it possible to write a function like this:

 zipn n list_1 list_2 list_3 ... list_n

 which implements zip3 for n=3, zip4 for n=4 etc.? Looks like variable
 number
 of arguments are possible, like printf shows, so a general zipn should be
 possible, too. If it is possible, why there are functions like zip5 and
 not
 just zipn?


Template Haskell can also be used to generate appropriate code for zipn (in
fact, the original paper on TH even uses this as an example [1]).  But
again, this approach only works if the value of n is known at compile time.

-Brent

[1] http://www.haskell.org/th/papers/meta-haskell.ps
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Defining new operators

2007-08-11 Thread Brent Yorgey
On 8/10/07, Shachaf Ben-Kiki [EMAIL PROTECTED] wrote:


 Also consider using:

  data Step = Step { ..., scenario :: Scenario, ... }


Just to expand on Shachaf's answer,  when defining a data type you can use a
special record syntax to give names to each of the components, like this:

data Monkey = M { species :: Species, color :: Color }

This automatically gives you functions called 'species' and 'color' which
you can apply to values of type Monkey to extract the relevant components.
So in your case, you could write something like

data Step = Step { ..., owner :: Scenario, ... }

...which would give you the 'owner' function you defined above for free,
without having to type it out.

To expand on Dan and Albert's answers, the 'functional idiom' would be to
just write 'owner x' -- introducing something like a different definition of
. to do 'record selection' might make things easier in the short term (i.e.
if you are used to programming in an OO paradigm) but seems quite
detrimental in the long term.  Trying to force Haskell to look and feel like
other languages you are used to is like taking two of the wheels off your
Porsche because you are used to riding a bicycle. =)

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


Re: [Haskell-cafe] Dynamic thread management?

2007-08-11 Thread Neil Bartlett
Hugh,

I certainly think it would be wrong to declare that NDP is doomed to
failure... not because you would be making an enemy of SPJ (I'm pretty
sure you wouldn't!) but because it actually aims to solves a less
ambitious problem: the problem of parallelising the SAME task applied
to different data, rather than a collection of arbitrary tasks.
Because the task does not change, we know that e.g. taking half the
data cuts the amount of work in half. Therefore an up-front scheduling
approach can work.

If you fast forward to about 42 minutes into the London HUG video, you
see that Simon talks about the problem of parallelizing (f x) + (g y),
and says that he spent quite a lot of time in the eighties trying to
make this game go fast [..] and the result was pretty much abject
failure.

You're absolutely right that a dynamic/adaptive approach is the only
one that will work when the tasks are of unknown size. Whether this
approach is as easy as you think is open for you to prove. I look
forward to testing your VM implementation, or at the very least
reading your paper on the subject ;-)

Regards,
Neil


On 8/11/07, Hugh Perkins [EMAIL PROTECTED] wrote:
 On 8/11/07, Thomas Conway [EMAIL PROTECTED] wrote:
  There are many papers about this in the Parallel Logic Programming
  area. It is commonly called Embarrassing Parallelism.

 Ah, I wasnt very precise ;-)  I didnt mean I dont understand the
 problem; I meant I dont understand why people think it is difficult to
 solve ;-)  (And then I tried to explain by examples why it is easy,
 but it is true that my communication sucks ;-) )

  you'll only get a benefit if you can break xs into chunks
 of e.g. 10^3 elements or more, and more like 10^5 or more for more
 usual 'f's.

 Actually, the number of elements is irrelevant.  The only measure that
 is important is how long the function is taking to execute, and
 whether it is parellizable.

 Example, the following only has 3 elements but will take a while to run:

 strPrtLn $ sum $ map getNumberPrimes [1024, 2048, 4096 ]

 The following has 10 million elements but runs quickly:

 strPrtLn $ sum $ map (+1) [1..1000 ]

 In the second, we start the function running, in a single thread, and
 after a second, the function has already finished, so great! Were
 done!

 In the first, we start the function running, in a single thread.
 After a second the function is still running, so we look at what is
 taking the time and whether it is parallelizable.

 Turns out the vm has been chugging away on the map for the last
 second, and that that maps are parallelizeable, so we split the map
 into Math.Min( numberelements, number cores) pieces, which on a
 1024-core machine, given we have 3 elements, is Math.Min( 1024, 3 ),
 which is 3.

 So, we assign each of the 3 elements of the map to a thread.  So, now
 we're using 3 of our 64 cores.

 A second later, each thread is still chugging away at its element, so
 we think, ok, maybe we can parallelize more, because we still have 61
 threads/cores available, so now we look at the getNumberOfPrimes
 function itself, and continue the above type of analysis.

 This continues until all 64 cores have been assigned some work to do.

 Whenever a thread finishes, we look around for some work for it to do.
  If there is some, we assign it.  If there isnt, we look around for an
 existing thread that is doing something parallelizeable, and split it
 into two pieces, giving one to the old thread, and one to the
 available thread.

 Not sure why this is perceived as difficult (added the word
 perceived this time ;-) ).  I think the main barrier to
 understanding why it is easy is understanding that this needs to be
 done from a VM, at runtime.  It is not possible to do it statically at
 compilation, but I really need to finish watching SPJ's video before
 declaring that SPJ's proposal is doomed to fail ;-)  Not least,
 probably not good to make an enemy of SPJ ;-)
 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe

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


Re: [Haskell-cafe] Re: zip3, zip4 ... - zipn?

2007-08-11 Thread Per Vognsen
On 8/11/07, apfelmus [EMAIL PROTECTED] wrote:
 Frank Buss schrieb:
  Is it possible to write a function like this:
 
  zipn n list_1 list_2 list_3 ... list_n
 
  which implements zip3 for n=3, zip4 for n=4 etc.? Looks like variable number
  of arguments are possible, like printf shows, so a general zipn should be
  possible, too. If it is possible, why there are functions like zip5 and not
  just zipn?

 What type would this function have? It's not possible to formulate this
 type in Haskell98. The problem is that the number of arguments cannot be
 determined statically, i.e. it depends on the value of  n  at run-time.
 There are languages more freaky than Haskell (like Agda or Epigram )
 that can do that (without dynamic typing, that is!), they are called
 dependently typed.

 However, type-class hackery (or type synonym families once they're
 available in GHC) can be used to do something like that if you give the
 value of n at compile-time. I won't dwell into that, though.

 Also, applicative functors can help

GHCi :m +Control.Applicative
GHCi (\x y z - x*(y+z)) $ ZipList [1,2,3]
  * ZipList [-1,0,1] * ZipList [1,1,1]
ZipList [0,2,6]
GHCi

 (the second command is a single line.)

Applicative functors can indeed help:

(,,,) $ [1,2,3] * [-1,0,1] * [1,1,1] * [0,2,6]

You just use n-1 commas when you want the effect of zipn.

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


Re: [Haskell-cafe] Dynamic thread management?

2007-08-11 Thread Brian Hurt


You guys might also want to take a look at the Cilk programming language, 
and how it managed threads.  If you know C, learning Cilk is about 2 hours 
of work, as it's C with half a dozen extra keywords and a few new 
concepts.  I'd love to see Cilk - C + Haskell as a programming language.


The key idea of Cilk is that it's easier to deparallelize than it is to 
parallelize, especially automatically.  So the idea is that the program is 
written incredibly parallel, with huge numbers of microthreads, which are 
(on average) very cheap to spawn.  The runtime then deparallelizes the 
microthreads, running multiple microthreads sequentially within a single 
real thread (a worker thread).  Microthreads that live their entire life 
within a single real thread are cheap to spawn (as in not much more 
expensive than a normal function call cheap).


The problem that Cilk runs into is that it's, well, C.  It doesn't deal 
with contention at well at all- a single microthread blocking blocks the 
whole worker thread- meaning, among other things, that you can have false 
deadlocks, where one microthread blocks on another microthread in the 
same real thread, and thus acts like it's deadlocked even though it really 
isn't.  You have greatly increased the likelyhood of raceconditions as 
well (mutable data and multithreading just don't mix).  Plus you have all 
the normal fun you have with C bugs- wild pointers, buffer over runs, etc.


All of which you avoid if you replace the C aspects of Cilk with Haskell. 
With STM you avoid the deadlock problem entirely, and with immutable data 
(except for carefully coded monads) you avoid the whole race condition 
problem.  Plus all the normal advantages Haskell has over C.


Just my $0.02.

Brian

On Sat, 11 Aug 2007, Neil Bartlett wrote:


Hugh,

I certainly think it would be wrong to declare that NDP is doomed to
failure... not because you would be making an enemy of SPJ (I'm pretty
sure you wouldn't!) but because it actually aims to solves a less
ambitious problem: the problem of parallelising the SAME task applied
to different data, rather than a collection of arbitrary tasks.
Because the task does not change, we know that e.g. taking half the
data cuts the amount of work in half. Therefore an up-front scheduling
approach can work.

If you fast forward to about 42 minutes into the London HUG video, you
see that Simon talks about the problem of parallelizing (f x) + (g y),
and says that he spent quite a lot of time in the eighties trying to
make this game go fast [..] and the result was pretty much abject
failure.

You're absolutely right that a dynamic/adaptive approach is the only
one that will work when the tasks are of unknown size. Whether this
approach is as easy as you think is open for you to prove. I look
forward to testing your VM implementation, or at the very least
reading your paper on the subject ;-)

Regards,
Neil


On 8/11/07, Hugh Perkins [EMAIL PROTECTED] wrote:

On 8/11/07, Thomas Conway [EMAIL PROTECTED] wrote:

There are many papers about this in the Parallel Logic Programming
area. It is commonly called Embarrassing Parallelism.


Ah, I wasnt very precise ;-)  I didnt mean I dont understand the
problem; I meant I dont understand why people think it is difficult to
solve ;-)  (And then I tried to explain by examples why it is easy,
but it is true that my communication sucks ;-) )


you'll only get a benefit if you can break xs into chunks

of e.g. 10^3 elements or more, and more like 10^5 or more for more
usual 'f's.

Actually, the number of elements is irrelevant.  The only measure that
is important is how long the function is taking to execute, and
whether it is parellizable.

Example, the following only has 3 elements but will take a while to run:

strPrtLn $ sum $ map getNumberPrimes [1024, 2048, 4096 ]

The following has 10 million elements but runs quickly:

strPrtLn $ sum $ map (+1) [1..1000 ]

In the second, we start the function running, in a single thread, and
after a second, the function has already finished, so great! Were
done!

In the first, we start the function running, in a single thread.
After a second the function is still running, so we look at what is
taking the time and whether it is parallelizable.

Turns out the vm has been chugging away on the map for the last
second, and that that maps are parallelizeable, so we split the map
into Math.Min( numberelements, number cores) pieces, which on a
1024-core machine, given we have 3 elements, is Math.Min( 1024, 3 ),
which is 3.

So, we assign each of the 3 elements of the map to a thread.  So, now
we're using 3 of our 64 cores.

A second later, each thread is still chugging away at its element, so
we think, ok, maybe we can parallelize more, because we still have 61
threads/cores available, so now we look at the getNumberOfPrimes
function itself, and continue the above type of analysis.

This continues until all 64 cores have been assigned some work to do.

Whenever a 

Re: [Haskell-cafe] Dynamic thread management?

2007-08-11 Thread Andrew Coppin

Brian Hurt wrote:
The key idea of Cilk is that it's easier to deparallelize than it is 
to parallelize, especially automatically.  So the idea is that the 
program is written incredibly parallel, with huge numbers of 
microthreads, which are (on average) very cheap to spawn.  The runtime 
then deparallelizes the microthreads, running multiple microthreads 
sequentially within a single real thread (a worker thread).  
Microthreads that live their entire life within a single real thread 
are cheap to spawn (as in not much more expensive than a normal 
function call cheap).


That's so absurd, it might even work!

I quite like the concept though - rather than asking what can we make 
parallel?, you say what should we do serially? That sounds like an 
easier question to answer...


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


Re: [Haskell-cafe] Dynamic thread management?

2007-08-11 Thread Sebastian Sylvan
On 11/08/07, Brian Hurt [EMAIL PROTECTED] wrote:

 You guys might also want to take a look at the Cilk programming language,
 and how it managed threads.  If you know C, learning Cilk is about 2 hours
 of work, as it's C with half a dozen extra keywords and a few new
 concepts.  I'd love to see Cilk - C + Haskell as a programming language.

 The key idea of Cilk is that it's easier to deparallelize than it is to
 parallelize, especially automatically.  So the idea is that the program is
 written incredibly parallel, with huge numbers of microthreads, which are
 (on average) very cheap to spawn.  The runtime then deparallelizes the
 microthreads, running multiple microthreads sequentially within a single
 real thread (a worker thread).  Microthreads that live their entire life
 within a single real thread are cheap to spawn (as in not much more
 expensive than a normal function call cheap).

 The problem that Cilk runs into is that it's, well, C.  It doesn't deal
 with contention at well at all- a single microthread blocking blocks the
 whole worker thread- meaning, among other things, that you can have false
 deadlocks, where one microthread blocks on another microthread in the
 same real thread, and thus acts like it's deadlocked even though it really
 isn't.  You have greatly increased the likelyhood of raceconditions as
 well (mutable data and multithreading just don't mix).  Plus you have all
 the normal fun you have with C bugs- wild pointers, buffer over runs, etc.

 All of which you avoid if you replace the C aspects of Cilk with Haskell.
 With STM you avoid the deadlock problem entirely, and with immutable data
 (except for carefully coded monads) you avoid the whole race condition
 problem.  Plus all the normal advantages Haskell has over C.


How is this any better than using par in Haskell?

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


[Haskell-cafe] Haddock: documenting parameters of functional arguments

2007-08-11 Thread Henning Thielemann

I like to write documentation comments like

fix ::
  (   a {- ^ local argument -}
   - a {- ^ local output -} )
  - a {- ^ global output -}

but Haddock doesn't allow it. Or is there a trick to get it work?
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re[2]: [Haskell-cafe] Dynamic thread management?

2007-08-11 Thread Bulat Ziganshin
Hello Brian,

Saturday, August 11, 2007, 8:35:49 PM, you wrote:

 The key idea of Cilk is that it's easier to deparallelize than it is to
 parallelize, especially automatically.  So the idea is that the program is
 written incredibly parallel, with huge numbers of microthreads, which are
 (on average) very cheap to spawn.  The runtime then deparallelizes the
 microthreads, running multiple microthreads sequentially within a single
 real thread (a worker thread).

this idea is in wide use now: it's how ghc, erlang, ruby and virtually
any other interpreting languages work :))


-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]

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


Re: [Haskell-cafe] Explaining monads

2007-08-11 Thread Ronald Guida

David Menendez wrote:
 Be sure to read sigpfe's You could have invented monads! and the
 Wadler paper.

 
http://sigfpe.blogspot.com/2006/08/you-could-have-invented-monads-and.html

 http://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf

 Most tutorials try to explain what a monad *is*, but these focus
 more on why they're a useful way to organize code. In my experience,
 being able to use a monad is more important than understanding the
 theory.

Hey, now I know what a monad is!  What I missed in all those tutorials
is that a monad is an *abstract base class*.  With this realization,
which I had after reading the sigfpe tutorial, everything makes sense
for me.

To review a basic OOP example, I can't illustrate what a Vehicle *is*
in general terms.  I can illustrate a Bicycle, a Car, a Boat, a Plane,
a Submarine, a Hovercraft, a LARC-V, and many other examples of
instances of /subclasses/ of Vehicle, but I can't find anything that's
/just/ a Vehicle.  In OOP, Vehicle is an abstract base class.

The same thing applies for a Monad.  I can look at lots and lots of
instances, like Maybe, Either, List, State, Reader, Writer, IO, and
lots of others, but I can't produce an example that's /just/ a Monad.
Monad is an abstract base class, too.

Now if I had to explain What is a Vehicle, I would have to say A
Vehicle is a device that provides transportation.  When asked for
more details, I can specify the interface and provide examples of
instances.

 Interface for Vehicle: load, unload, goto
 Instances of Vehicle: Bicycle, Car, Plane, Boat, etc.

Given the question What is a Monad, I would have to say A Monad is
a device for sequencing side-effects.  When asked for more details, I
can specify the interface and provide examples of instances.

 Interface for Monad: return, bind
 Instances of Monad: Maybe, Either, List, State, etc.

What is particularly stupefying for me is that I missed the fact that
Monad is obviously an abstract base class: Monad is declared as a
type-class!

Now the hard part.  As far I currently know - and I could be wrong:

(1) Monad, Comonad and Arrow are all abstract base classes.

(2) Monad, Comonad and Arrow are all devices for sequencing
   side-effects.

(3) Monad and Comonad are both specializations of Arrow.

Given the question What is an Arrow, I would have to say An Arrow
is a device for sequencing side-effects.  When asked for more
details, I can specify the interface and provide examples of
instances.

This leads directly to the question What makes a Monad special,
compared to an Arrow?  Right now, the clues I have are:

(1) Every monad is equivalent to a Kleisli arrow.

(2) The ArrowApply class is equivalent to the Monad class.

I can restate the question: What is special about ArrowApply,
compared to Arrow?  I see that an arrow accepts some inputs, performs
a computation, possibly with side-effects, and generates some outputs.

In particular, suppose I create instances of Arrow that accept two
inputs (as a pair) and produce one output.  Some of these instances
(i.e. ArrowApply) are special: I can provide, as the two inputs, (1)
an Arrow that accepts one input and one output, and (2) an input
suitable for that Arrow.  The output that I get is the result of
feeding input (2) to input (1) to get a result, *and* somehow
combining the side-effects of both arrows.

The only way an ArrowApply can combine the side effects of two arrows
and still obey the Arrow laws is through an operation that takes an
(arrow nested inside an arrow) and collapses it into a sigle arrow.
That's exactly what join does for monads.  So, ArrowApply is
special, compared to Arrow, because ArrowApply has a join operation,
but Arrow doesn't.  Clear as mud!

The question remains: What is special about Monad or ArrowApply,
compared to Arrow? or What is more general about Arrow, compared to
Monad or ArrowApply?

-- Ron

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


[Haskell-cafe] Re: zip3, zip4 ... - zipn?

2007-08-11 Thread Chung-chieh Shan
Frank Buss [EMAIL PROTECTED] wrote in article [EMAIL PROTECTED] in 
gmane.comp.lang.haskell.cafe:
 Is it possible to write a function like this:
 
 zipn n list_1 list_2 list_3 ... list_n
 
 which implements zip3 for n=3, zip4 for n=4 etc.? Looks like variable number
 of arguments are possible, like printf shows, so a general zipn should be
 possible, too. If it is possible, why there are functions like zip5 and not
 just zipn?

Check out:

Fridlender, Daniel, and Mia Indrika. 2000. Do we need dependent
types? Journal of Functional Programming 10(4):409-415.
http://www.math.chalmers.se/~indrika/jfp.ps.gz

McBride, Conor. 2002. Faking it: Simulating dependent types in
Haskell. Journal of Functional Programming 12(4-5): 375-392.

-- 
Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig
Remember Hirosima 1945-08-06, Nagasaki 1945-08-09.
http://petitions.pm.gov.uk/Free-Vanunu/ http://www.vanunu.org/

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


[Haskell-cafe] Re: default for quotRem in terms of divMod?

2007-08-11 Thread Henning Thielemann

Btw. is there any application, where 'quot' and 'rem' are needed? All
occurrences of 'quot' and 'rem' I found in code so far were actually wrong
and should have been 'div' and 'mod'.

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


Re: [Haskell-cafe] Explaining monads

2007-08-11 Thread Stefan O'Rear
On Sat, Aug 11, 2007 at 03:00:04PM -0400, Ronald Guida wrote:
 The question remains: What is special about Monad or ArrowApply,
 compared to Arrow? or What is more general about Arrow, compared to
 Monad or ArrowApply?

If all you have is an Arrow, then you must make up your mind what you're
going to do ahead of time.

ArrowChoice gives you the ability to make basic yes or no decisions at
run time.

ArrowApply gives you arbitrary computed jumps.


Sometimes it's useful to restrict what you can do.  Duponcheel and
Swierstra wrote a parser library as an Arrow; because it forced you to
decide the parsing structure ahead of time, their library had enough
information to build LR-type parsing tables, and thus to do yacc-style
error correction.  (Nobody found it useful enough to use, but it still
makes a nice demonstration of why plain Arrow is sometimes better.)

Conversely, some applications *need* the extra freedom.  Imagine trying
to write an interpreter for a toy language with I/O, and IO is a plain
Arrow and not a Monad.  You can read input and parse it, but you can't
actually do IO because the IO you need to do, depends on the input you
read - precisely what Arrow forbids!

Stefan


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


Re: [Haskell-cafe] zip3, zip4 ... - zipn?

2007-08-11 Thread Stefan O'Rear
On Sat, Aug 11, 2007 at 05:27:19PM +0800, Hugh Perkins wrote:
 I was looking for something like this too.

 Note that Erlang can do this ;-)  but Erlang is probably not so
 strongly typed, so it's easier to do?

I think the main issue is that Erlang doesn't use currying (IIRC).
Currying makes it MUCH harder to implement varargs functions.  (We
thought this was a good tradeoff - partial applications give Haskell
much more power than varargs would have.)

(Unfortunately I don't know of any good languages with powerful type
systems and vararg functions that can take advantage of powerful
types...  I'd love to give example code here :))

Stefan


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


Re: [Haskell-cafe] Re: default for quotRem in terms of divMod?

2007-08-11 Thread Derek Elkins
On Sat, 2007-08-11 at 21:10 +0200, Henning Thielemann wrote:
 Btw. is there any application, where 'quot' and 'rem' are needed? All
 occurrences of 'quot' and 'rem' I found in code so far were actually wrong
 and should have been 'div' and 'mod'.
 
 http://www.haskell.org/haskellwiki/Things_to_avoid#Forget_about_quot_and_rem

quotRem is faster than divMod, and my understanding is that even divMod
is arguably broken.

http://www.cs.uu.nl/~daan/download/papers/divmodnote-letter.pdf

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


Re: [Haskell-cafe] howto install ghc-6.7.* ?

2007-08-11 Thread Stefan O'Rear
On Sat, Aug 11, 2007 at 11:44:17AM +0200, Marc A. Ziegert wrote:
 i just don't get it.
 please, can anybody explaim me how to do that?
 i tried it the last few days with ghc-6.7.20070807, ghc-6.7.20070809, and 
 ghc-6.7.20070810.
 it always results in a broken library (without Prelude):
 
 # ghc-pkg list
 /usr/local/lib/ghc-6.7.20070810/package.conf:
 {ghc-6.7.20070810}, rts-1.0
 
 i did this on my gentoo-i386-box (pretty old, takes 1h for quick build, 3.5h 
 without mk/build.mk):
 
 T=20070810
 tar xjf ghc-6.7.$T-src.tar.bz2 
 tar xjf ghc-6.7.$T-src-extralibs.tar.bz2 
 cd ghc-6.7.$T
 (
 #echo BuildFlavour = quick
 #cat mk/build.mk.sample
 echo HADDOCK_DOCS = YES
 )  mk/build.mk
 ./configure  ( time nice -n 19 make all install )
 
 
 those extralibs seem to be installed in
  /usr/local/lib/ghc-6.7.20070810/lib/
 but registered in
  ghc-6.7.20070810/driver/package.conf.inplace
 instead of
  /usr/local/lib/ghc-6.7.20070810/package.conf

Last time I built GHC, I needed to run 'sh boot' right before configure.
Don't know if this has anything to do with your problem, however.

(It would also be a Good Idea to add 21 | tee -a make.log to that
command line, and look at the logs afterward...)

Stefan


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


[Haskell-cafe] IO within parser

2007-08-11 Thread Gregory Propf
I've been struggling with writing a parser that needs to parse include files 
within source files.  So far I cannot get this to work (in reality to get work 
done I wrote a kludge that returns a list of include filenames to be run later 
in a pure IO function.  I realized that this just amounted to creating my own 
half-assed monad system so I really don't want to use this approach).  I have 
read the tutorials I could find on monad transformers but I still don't see 
what's going on.  I'm using the Parsec parser library. Here's an simple example 
of what I've tried.  I also tried using liftIO and got a message about needing 
to add an instance of MonadIO.  This made more sense but the type of liftIO is 
baffling

class Monad m = MonadIO m  where
liftIO :: IO a - m a

But how do you define this function?  There is no constructor for IO a that 
you can take apart.

Anyway, here is the code that just uses lift. Keep in mind that the outer monad 
is just GenParser Char st [Char].  I'm guessing this is wrong and I should 
have a transformer monad as the outer layer.  But which one?  and how to use it?

pio = do {
 s - many1 alphaNum;
 input - lift (readFile s);
 return input;
   }

go6 = runParser pio ()  This is a test

=
ghc output from trying to load this is
=


Couldn't match kind `* - * - *' against `(* - *) - * - *'
When matching the kinds of `GenParser Char :: * - * - *' and
   `t :: (* - *) - * - *'
  Expected type: GenParser Char st
  Inferred type: t IO
In a 'do' expression: lift (writeFile Foo s)





  

Fussy? Opinionated? Impossible to please? Perfect.  Join Yahoo!'s user panel 
and lay it on us. http://surveylink.yahoo.com/gmrs/yahoo_panel_invite.asp?a=7 
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO within parser

2007-08-11 Thread Andrew Coppin

Gregory Propf wrote:
I've been struggling with writing a parser that needs to parse include 
files within source files.  So far I cannot get this to work (in 
reality to get work done I wrote a kludge that returns a list of 
include filenames to be run later in a pure IO function.  I realized 
that this just amounted to creating my own half-assed monad system so 
I really don't want to use this approach).  I have read the tutorials 
I could find on monad transformers but I still don't see what's going 
on.  I'm using the Parsec parser library. Here's an simple example of 
what I've tried.  I also tried using liftIO and got a message about 
needing to add an instance of MonadIO.  This made more sense but the 
type of liftIO is baffling


The fun part is that Parsec already has a feature for include files... 
(I can't remember where the heck it is or how you use it though.)


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


Re: [Haskell-cafe] Re: zip3, zip4 ... - zipn?

2007-08-11 Thread Marc Weber
 Also, applicative functors can help
 
   GHCi :m +Control.Applicative
   GHCi (\x y z - x*(y+z)) $ ZipList [1,2,3]
 * ZipList [-1,0,1] * ZipList [1,1,1]
   ZipList [0,2,6]
   GHCi
http://www.soi.city.ac.uk/~ross/papers/Applicative.pdf
quote The general scheme is as follows:
(page 2)

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


Re: [Haskell-cafe] Re: default for quotRem in terms of divMod?

2007-08-11 Thread Isaac Dupree

Henning Thielemann wrote:

Btw. is there any application, where 'quot' and 'rem' are needed? All
occurrences of 'quot' and 'rem' I found in code so far were actually wrong
and should have been 'div' and 'mod'.

http://www.haskell.org/haskellwiki/Things_to_avoid#Forget_about_quot_and_rem


Yes, my implementation of Integer in terms of lists of Int, deliberately 
uses the symmetry of quotRem in order to store negative numbers as the 
negation of all elements of the positive number, and be able to 
virtually ignore the signs most of the time.  (Also because quotRem is 
usually faster, I figured it made sense to use that technique.)  (It 
doesn't make any difference on numbers that cannot be negative, also.) 
Everywhere else I remember when coding, div/mod were the correct ones to 
use (even back when I was coding in C, I wished I had that rounding 
behavior some time).


I do think that if you almost always want to _use_ div and mod, you 
should be able to just define div and mod too (not quot and rem) -- one 
reason I brought up the issue :)


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


Re: [Haskell-cafe] Re: default for quotRem in terms of divMod?

2007-08-11 Thread Isaac Dupree

Isaac Dupree wrote:
I do think that if you almost always want to _use_ div and mod, you 
should be able to just define div and mod too (not quot and rem)


that was unclear - I mean you should have that choice, not that it 
should be disallowed to define quot and rem only!


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


Re: [Haskell-cafe] howto install ghc-6.7.* ?

2007-08-11 Thread Ryan Dickie
Same problem here. I downloaded the ghc-6.7.20070811.tar.bz2 snapshot build
on amd64 under ubuntu.

From the README
 The sh boot step is only necessary if this is a tree checked out
 from darcs.  For source distributions downloaded from GHC's web site,
 this step has already been performed.



On 8/11/07, Marc A. Ziegert [EMAIL PROTECTED] wrote:

 i just don't get it.
 please, can anybody explaim me how to do that?
 i tried it the last few days with ghc-6.7.20070807, ghc-6.7.20070809, and
 ghc-6.7.20070810.
 it always results in a broken library (without Prelude):

 # ghc-pkg list
 /usr/local/lib/ghc-6.7.20070810/package.conf:
 {ghc-6.7.20070810}, rts-1.0

 i did this on my gentoo-i386-box (pretty old, takes 1h for quick build,
 3.5h without mk/build.mk):

 T=20070810
 tar xjf ghc-6.7.$T-src.tar.bz2
 tar xjf ghc-6.7.$T-src-extralibs.tar.bz2
 cd ghc-6.7.$T
 (
 #echo BuildFlavour = quick
 #cat mk/build.mk.sample
 echo HADDOCK_DOCS = YES
 )  mk/build.mk
 ./configure  ( time nice -n 19 make all install )


 those extralibs seem to be installed in
 /usr/local/lib/ghc-6.7.20070810/lib/
 but registered in
 ghc-6.7.20070810/driver/package.conf.inplace
 instead of
 /usr/local/lib/ghc-6.7.20070810/package.conf
 .


 - marc

 ___
 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] Dynamic thread management?

2007-08-11 Thread Brian Hurt



On Sat, 11 Aug 2007, Sebastian Sylvan wrote:


How is this any better than using par in Haskell?


Mainly how the threads are actually scheduled.  Mind you, I'm an 
*incredible* Haskell newbie, so take all of my comments with a 5-pound 
salt block, but as I understand how the current implementation of parallel 
Haskell works, all threads spawned go into a communal heap.  When a thread 
blocks, it's put back into the communal queue, and a new thread is 
selected to run by the worker thread.


In Cilk, the task structure is more tree-like.  When thread A spawns 
thread B, the worker thread stops executing thread A and starts executing 
thread B.  When thread B exits, the worker thread then resumes thread A. 
So in any given point in time, the worker thread has a stack of processes 
waiting for subthreads to complete so they can be resumed- not unlike 
function calls in other languages, or nested lazy blocks in Haskell.


When a worker thread runs out of work to do, when it has no more threads 
to execute, it picks another worker thread at random, and asks the other 
worker thread for work to do.  The other worker thread (assuming it has 
work to do) then picks the microthread at the bottom of the resume stack, 
that is farthest away from being resumed, and passes that microthread's 
state to the original worker thread.


From the user program's perspective, this is no different from the current 
implementation.  Threads get spawned, get executed in some unspecified 
order, and then complete.


What's interesting (to me, at least) are the optimization opportunities 
this model provides that the shared-queue model doesn't.  Consider the 
following structural model: we have a two-tiered heap.  Each worker thread 
has it's own local heap, which only microthreads it is managing can see. 
Plus there is a global heap with objects that all microthreads in all 
worker threads can see.  Objects are originally allocated in the local 
heap.  When a microthread to start being executed on another worker 
thread, all objects it can see (reach, in the conservative GC sense) are 
promoted to the global heap.


The advantage of all of this is that now we can easily distinguish between 
objects that can be seen from other real threads, and those that can't. 
All of the mutable data structures- tvars, lazy thunks, everything- can be 
much more cheaply implemented if you know that no other thread can access 
them.


Take the example of a parallel map, where I'm using a tvar in my map 
function.  The likelyhood is that all of the (short-lived) microthreads 
I'm spawning will execute on the same worker thread- and that thus the 
tvar will never leave the local heap, and thus can be optimized down to 
something close to a single-threaded mvar.  I have, via optimization, 
turned a parallel map and a synchronized tvar back into something 
approaching a serial map and an mvar.


Brian

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


Re: [Haskell-cafe] zip3, zip4 ... - zipn?

2007-08-11 Thread Stefan O'Rear
On Sun, Aug 12, 2007 at 12:56:31PM +1000, Alexis Hazell wrote:
 On Sunday 12 August 2007 05:24, Stefan O'Rear wrote:
 
  Currying makes it MUCH harder to implement varargs functions. 
 
 That's interesting - why is that the case?

varsum 2 3   -- varsum receives 2, and returns a function, which when
 -- passed 3, returns 5
varsum 2 3 4 -- varsum receives 2, and returns a function, which when
 -- passed 3, returns a function that when passed 4 returns
 -- 9.

Because of this, the number of arguments must somehow be passed
out-of-band; but then the type of the whole function (usually) must
depend on the control parameter, requiring dependent types.

Stefan


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


[Haskell-cafe] Infinity v0.1

2007-08-11 Thread Austin Seipp
Hello!

Over the past couple of days I've been working on an IRC bot in the
essence of lambdabot; that is, it should be extendable through plugins
and plugins should be easy to write, modify and contribute. I also
wanted the bot to be small in terms of LOC (as of 0.1, about ~360
including the two bundled plugins,) but still be usable.

Well, now I have something to show for it, and I introduce infinity v0.1:

http://austin.youareinferior.net/infinity-0.1.tar.gz
(there is no darcs repo yet, although I have emailed someone about a
possible account for darcs.haskell.org.)

Everything from building to writing plugins should become fairly self
evident from reading the README. You will need the hs-plugins to use
it. As it stands, the bot is incredibly primitive and there are almost
no plugins (I only wrote 'hello world' and 'goodbye world' plugins to
test the code as it moved forward) as of yet, however, I had fun with
this thing and I hope maybe someone could do something interesting
with it.

There're some parts of the code that I'm not particularly happy with.
For the 0.2 release I have a couple of goals in mind:

1. To move the basic ad-hoc IRC parsing code (lots of drop and
dropWhile and whatnot) to a more robust implementation such as parsec.
This should hopefully clean up some of the code I'm not on good terms
with.
2. To add support for in-situ reloading and re-compilation of modules,
so you won't even have to restart the bot if you update a plugin. This
will probably require some reworking of my threading code so that the
environment stays safe and stable (STM?)
3. To move all of the built-in core commands to plugins as well; this
will probably require encapsulating plugins in a monad (StateT)
henceforth.

I'm not exactly the most advanced haskell programmer ever born, but I
enjoyed working on this code and while it isn't and probably won't
ever be the next lambdabot, I hope someone can learn something from it
or just have fun with it. If anybody would like to take the time to
write a plugin or something for some interesting purpose, I would be
happy to include it in the source tree (I'm sure you guys can come up
with something more interesting than I can.)

I would really appreciate any and all comments on the code. I still
feel myself to be in an 'intermediate' area with Haskell, so anything
you guys can add that would improve the code would be incredibly
appreciated.

PS: I've only tested this on an i386 linux box so if anybody here can
confirm it works on other systems (bsd, solaris?) where hs-plugins is
available, that would be awesome.

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


Re: [Haskell-cafe] Re: towards a new foundation for set theory with atoms

2007-08-11 Thread Brandon Michael Moore
On Fri, Aug 10, 2007 at 03:54:23PM -0700, Greg Meredith wrote:
 Haskellians,
 
 A quick follow up. If you look at the code that i have written there is a
 great deal of repeated structure. Each of these different kinds of sets and
 atoms are isomorphic copies of each other. Because, however, of the
 alternation discipline, i could see no way to abstract the structure and
 simplify the code. Perhaps someone better versed in the Haskellian mysteries
 could enlighten me.

You could take a less absolute view of the game, and describe each node
instead locally from the perspective of a player. Imagine Alice Bob and
Carol sitting around a table:

data ThreePlayers a b c =
   Next (ThreePlayer b c a)
 | Prev (ThreePlayers c a b)

In general you can get subgroups of a symmetric group as your sets of
colors this way (i.e, the set of elements of any group), I'm not quite
sure how much freedom you have in the sets of allowed transitions
(in particular, making some of the argument types identical can break
symmetry).

You could also go for the obvious big hammer, pretend that Haskell has
a strongly normalizing subset and encode inequality explicitly with
GADTs and such.

date Eq a b where Refl a a
data False
type Neq a b = Eq a b - False
-- might be trouble if a and b are only equal non-constructively?

data Red = Red
data Green = Green


data Set color where
  Red :: Neq Red color - Set Red - Set color
  ...

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


Fw: [Haskell-cafe] IO within parser

2007-08-11 Thread Gregory Propf
Well the docs ( http://legacy.cs.uu.nl/daan/download/parsec/parsec.html ) hint 
that setInput and getInput are good for this.  I can certainly how they *would* 
be - if I knew how to pull in files within the parse.  Actually I use those 
functions to do multiple recursive passes but of course you already have the 
output from the first pass in the parser there.  runParser only *looks* like it 
takes input from a file.  Actually it just parses the string you give it and 
uses the filename arg for error messages only.  You still need a way to pull 
the data into the string from the file.  

(Note: I accidentally sent this to Andrew instead of the list originally)

- Original Message 
From: Andrew Coppin [EMAIL PROTECTED]
To: haskell-cafe@haskell.org
Sent: Saturday, August 11, 2007 1:25:16 PM
Subject: Re: [Haskell-cafe] IO within parser

Gregory Propf wrote:
 I've been struggling with writing a parser that needs to parse include 
 files within source files.  So far I cannot get this to work (in 
 reality to get work done I wrote a kludge that returns a list of 
 include filenames to be run later in a pure IO function.  I realized 
 that this just amounted to creating my own half-assed monad system so 
 I really don't want to use this approach).  I have read the tutorials 
 I could find on monad transformers but I still don't see what's going 
 on.  I'm using the Parsec parser library. Here's an
 simple example of 
 what I've tried.  I also tried using liftIO and got a message about 
 needing to add an instance of MonadIO.  This made more sense but the 
 type of liftIO is baffling

The fun part is that Parsec already has a feature for include files... 
(I can't remember where the heck it is or how you use it though.)

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







  Fussy? Opinionated? Impossible to please? Perfect.  Join Yahoo!'s user 
panel and lay it on us.






   

Choose the right car based on your needs.  Check out Yahoo! Autos new Car 
Finder tool.
http://autos.yahoo.com/carfinder/___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe