Re: [Haskell-cafe] System.Exit

2007-07-05 Thread Stefan O'Rear
On Thu, Jul 05, 2007 at 02:04:32PM +1000, Thomas Conway wrote:
 Hi All,

 Can anyone tell me what System.Exit.exitWith is actually supposed to
 do? As far as I can tell, it seems to be a synonym of (return ()).

 Okay, I'll stop being provocative and try and be helpful.

 So I have a web server, which like the one in The Literature(TM),
 essentially has a main loop:

 doit sok = do
(reqSok,reqAddr) - Network.Socket.accept sok
forkIO (handleRequest reqSok reqAddr)
doit sok

 This is all well and good, but how do you *stop* a server? Well, you
 have a request (blah blash auth blah blah) which tells it to shut
 down, /quit for example.

 I have a function to handle the quit request that looks something like:

 quitHandler sok addr  = do
tidyUpEverything 
sendOkResponse sok
sClose sok
System.Exit.exitWith ExitSuccess

 All nice and simple. All except one detail: it doesn't actually work.

 It prints

 exit: ExitSuccess

 but the doit loop keeps going. Of course, it goes totally spacko,
 because of the call to tidyUpEverything, but it doesn't exit.

 So, if I set an IORef/TVar inside quitHandler which I inspect either
 just before or just after the call to Network.Socket.accept, I could
 exit the loop, but that only helps once the next request comes in.

 I contemplated a solution involving Control.Exception.throwTo, but I
 actually read the doco (!) which states the following:

 quote
 If the target thread is currently making a foreign call, then the
 exception will not be raised (and hence throwTo will not return) until
 the call has completed. This is the case regardless of whether the
 call is inside a block or not.
 /quote

 So no joy there.

 Ideas anyone?

 And is exitWith broken, or is it the doco that's broken?

The documentation says:
| Computation exitWith code throws ExitException code. Normally this
| terminates the program, returning code to the program's caller. Before
| the program terminates, any open or semi-closed handles are first
| closed.   

   
| 
| As an ExitException is not an IOError, exitWith bypasses the error
| handling in the IO monad and cannot be intercepted by catch from the
| Prelude. However it is an Exception, and can be caught using the
| functions of Control.Exception. This means that cleanup computations
| added with bracket (from Control.Exception) are also executed properly
| on exitWith.


Probably some part of your code is catching all exceptions, printing
them, and then ignoring them; thus negating the exit request.

If you want to ignore all exceptions, you can still use exitImmediately
from the unix package, but all the usual caveats (unflushed file
buffers, no synchronization, no profile output) apply.

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


[Haskell-cafe] Lightweight sequent calculus and linear abstractions

2007-07-05 Thread oleg

Conor McBride has posed an interesting problem:
implement constructors
  P v  for embedding pure values v
  Ofor holes
  f :$ a   for application, left-associative
and an interpreting function
  emmental
such that
  emmental (P (+) :$ (P (*) :$ O :$ P 10) :$ O) 4 2 = 42

I believe one can do better. There is no need for the :$ operation, and
there is no need for of lifting non-functional constants. The following code
demonstrates a more economical notation. The code essentially
implements Hypothetical Reasoning, considering an expression with
holes as an (intuitionistic) sequent. Each hole is one formula in the
antecedent. The formulas in the antecedent are ordered, so our logic 
is actually the relevance, substructural intuitionistic logic. The
function emmental takes the form of the Deduction Theorem (and its
implementation is the proof of the theorem). The test takes the form

 test_McBride = dt ((ih *! (10::Int)) +! ih) 4 2
  where ih = holet (undefined::Int)

and gives the predictable answer.

Another test, which shows that we can pile up holes (aka hypotheses)
at will, and they all line up:

 test7 = let exp = l1 (map succ) ((1::Int) !: ih !: ih !: ih !: [5])
 ih = holet (undefined::Int)
 deduced = dt exp
 in deduced 11 12 13
 -- [2,12,13,14,6]

 test_order = dt( (ih `p` ih) `p` (ih `p` ih) ) 1 2 3 4
  where ih = holet (undefined::Int)
 -- ((1,2),(3,4))

It is clear from our examples that our holes are monomorphically
typed; the lifted functions don't have to be. We could have
implemented things the other way around. We could have played with
more complex inferences when applying polymorphic functions to
polymorphic sequents. At present, we chose the simplest solution.
Here it is.

{-# OPTIONS -fglasgow-exts #-}
{-# OPTIONS -fallow-undecidable-instances #-}
{-# OPTIONS -fallow-overlapping-instances #-}
-- the extensions are merely for the sake of IsHypothetical below

-- Lightweight sequent calculus: computations on sequents

module SEQ where

-- Hypothetical value: one formula in the antecedent
newtype H a = H a

-- The primitive sequent: a |- a
hole :: H a - a
hole (H x) = x

-- The version of the above to make it easy to assign a specific type to it
holet :: a - H a - a
holet _ = hole


-- This class proves, by construction, the Deduction Theorem
-- x |- b == x - b
class DeductionTh seq r | seq - r where
dt :: seq - r

instance (IsHypothetical seq f, DeductionTh' f seq r)
= DeductionTh seq r where
dt = dt' (undefined::f)

class DeductionTh' f seq r | f seq - r where
dt' :: f - seq - r

instance DeductionTh y r = DeductionTh' HTrue (H x - y) (x-r) where
dt' _ hf = \x - dt (hf (H x))

instance DeductionTh' HFalse a a where
dt' _ = id


-- Lifting an a-b function to sequents
class Lift1 a b arg res | a b arg - res where
l1 :: (a-b) - (arg-res)

instance (IsHypothetical arg f, Lift1' f a b arg res)
= Lift1 a b arg res where
l1 = l1' (undefined::f)

class Lift1' f a b arg res | f a b arg - res where
l1' :: f - (a-b) - (arg-res)

instance Lift1 a b y b' = Lift1' HTrue a b (H x - y) (H x - b') where
l1' _ fn arg = \hx - l1 fn (arg hx)

-- here we assert a local functional dependency
instance TypeCast arg a = Lift1' HFalse a b arg b where
l1' _ fn arg = fn (typeCast arg)


test1 = dt True
test2 :: Int - Int
test2 = dt hole

test2' = dt (holet (1::Int))

test3 = dt (l1 not True)
test4 = dt (l1 not (holet False))

-- expected type error
-- test4' = dt (l1 not (holet (1::Int)))
test4'' = test4 False



-- Lifting an a-b-c function to two sequents
-- we should keep the order of formulas in the combined antecedent
-- The following is just a funnily written `append' of two sequences

class Lift2 a b c arg1 arg2 res | a b c arg1 arg2 - res where
l2 :: (a-b-c) - (arg1-arg2-res)

instance (IsHypothetical arg1 f1, 
  IsHypothetical arg2 f2,
  Lift2' f1 f2 a b c arg1 arg2 res)
= Lift2 a b c arg1 arg2 res where
l2 = l2' (undefined::f1) (undefined::f2)

class Lift2' f1 f2 a b c arg1 arg2 res | f1 f2 a b c arg1 arg2 - res where
l2' :: f1 - f2 - (a-b-c) - (arg1-arg2-res)

-- First, drain the antecedent formulas from arg1
instance Lift2 a b c y1 arg2 r
= Lift2' HTrue f2 a b c (H x1 - y1) arg2 (H x1 - r)
 where
 l2' _ _ fn arg1 arg2 = \hx1 - l2 fn (arg1 hx1) arg2

-- now, add the antecedent formulas from arg2, if any
instance Lift2 a b c x1 y2 r
= Lift2' HFalse HTrue a b c x1 (H x2 - y2) (H x2 - r)
 where
 l2' _ _ fn arg1 arg2 = \hx2 - l2 fn arg1 (arg2 hx2)

instance (TypeCast x1 a, TypeCast x2 b)
= Lift2' HFalse HFalse a b c x1 x2 c
 where
 l2' _ _ fn arg1 arg2 = fn (typeCast arg1) (typeCast arg2)


-- Time for tests

infixl 6 +!
infixl 7 *!
infixr 5 !:

x +! y = l2 (+) x y
x *! y = l2 (*) x y
x `p` y = l2 (,) x y

x !: y = l2 (:) x y


test5  = dt ((1::Int) +! (2::Int))
test51 = dt (holet (1::Int) +! (2::Int))
test51' = test51 10 -- 12

test52 = dt 

Re: [Haskell-cafe] folds with escapes

2007-07-05 Thread oleg

 Can you do dropWhile in terms of foldr?

One can write foldr that represents drop or dropWhile of the
original foldr. One can do even more: zip two folds. That is,
obtain a fold that is equivalent to zipping up two lists represented
by the original folds. Even furthermore, one can do all these things
without recursion (neither at the value level, nor at the type level).

http://okmij.org/ftp/Algorithms.html#zip-folds


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


Re[2]: [Haskell-cafe] Deadlock in real number multiplication (Was: Where's the problem ?)

2007-07-05 Thread Miguel
R Another interesting thing I've discovered is:

Prelude length [1..100]
R 100
Prelude Data.List.genericLength [1..100]
R *** Exception: stack overflow

R Maybe there is something wrong with Integer ? 

No, there is something wrong with genericLength:

Prelude Data.List.foldl (+) 0 $ map (const 1) [1..100] :: Int
*** Exception: stack overflow
Prelude Data.List.foldl' (+) 0 $ map (const 1) [1..100] :: Integer
100

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


Re: [Haskell-cafe] Binary serialization, was Re: Abstraction leak

2007-07-05 Thread Philip Armstrong

On Thu, Jul 05, 2007 at 08:50:42AM +1000, Donald Bruce Stewart wrote:
[useful stuff]

So, in fact pretty much everything I was looking for exists, in some
form or other!

It's just a bit hard to find at the moment, perhaps because none of
this stuff is regarded as 'core Haskell' by any of the tutorials,
books etc etc.

I'll have a play with some of the libraries mentioned upthread
anyway. Thanks everyone.

Phil

--
http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Binary serialization, was Re: Abstraction leak

2007-07-05 Thread Thomas Conway

I was explaining Haskell to a perl/python hacking friend recently and
characterized things thus:

Perl is a horrible language with fantastic libraries.
Haskell is a fantastic language with horrible libraries.

Actually, many of the libraries that exist for Haskell *are*
fantastic, it's just that Haskell lacks the *coverage* that Perl or
Python have.

cheers,
T.
--
Dr Thomas Conway
[EMAIL PROTECTED]

Silence is the perfectest herald of joy:
I were but little happy, if I could say how much.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] System.Exit

2007-07-05 Thread Tomasz Zielonka
On Wed, Jul 04, 2007 at 11:16:20PM -0700, Stefan O'Rear wrote:
 The documentation says:
 | Computation exitWith code throws ExitException code. Normally this
 | terminates the program, returning code to the program's caller. Before
 | the program terminates, any open or semi-closed handles are first
 | closed. 
   

 | 
 | As an ExitException is not an IOError, exitWith bypasses the error
 | handling in the IO monad and cannot be intercepted by catch from the
 | Prelude. However it is an Exception, and can be caught using the
 | functions of Control.Exception. This means that cleanup computations
 | added with bracket (from Control.Exception) are also executed properly
 | on exitWith.
 
 Probably some part of your code is catching all exceptions, printing
 them, and then ignoring them; thus negating the exit request.

I think the problem here is that uncaught exception are not propagated from
child threads to the main thread (I'm not claiming that they should be)
and ExitException only ends the program when caught in the main thread,
as it seems. Try this:

import Control.Concurrent
import System.Exit

main = do
forkIO $ exitWith ExitSuccess
threadDelay 1000

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


[Haskell-cafe] Write a library today! Was: Binary serialization, was Re: Abstraction leakAKa

2007-07-05 Thread Donald Bruce Stewart
drtomc:
 I was explaining Haskell to a perl/python hacking friend recently and
 characterized things thus:
 
 Perl is a horrible language with fantastic libraries.
 Haskell is a fantastic language with horrible libraries.
 
 Actually, many of the libraries that exist for Haskell *are*
 fantastic, it's just that Haskell lacks the *coverage* that Perl or
 Python have.

Yes, and we know exactly what to do about this. hackage.haskell.org is
growing by a few packages a week -- and anyone who binds to any C lib
should just upload their stuff.

So ... if you're reading this message -- please upload a library today,
and more than just a few of us might have nice Haskell jobs tomorrow!

-- Don

P.S.  Maybe we should run 'bindathons' or have CPAN-style contests to
get new libraries written? If you're bored, write a binding to some C
lib, that python, ruby or perl have already got a binding to.  Do it!
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] folds with escapes

2007-07-05 Thread Claus Reinke

Can you do dropWhile in terms of foldr?  I don't see how.
If you are really keen, you might want to try altering the working  
backwards with tuples version into one which is properly lazy (many  
people who read the paper pointed out the omission).


you might want to mention the story of the predecessor function in church 
numerals (where data structures are represented as their right folds, and 
the predecessor function goes against the grain of that recursion, but can
be defined using pairing/returning functions)? 


for some history/anecdotes:

   The Impact of the Lambda Calculus in Logic and Computer Science,
   Barendregt, Bulletin of Symbolic Logic, 1997, section 2, paragraph 2
   http://citeseer.ist.psu.edu/barendregt97impact.html


for the tupling trick applied to dropWhile and primitive recursion, Graham's
tutorial has already been mentioned:

   A tutorial on the universality and expressiveness of fold
   Graham Hutton. Journal of Functional Programming, 1999, section 4
   http://www.cs.nott.ac.uk/~gmh/bib.html#fold

claus

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


[Haskell-cafe] Re: Deadlock in real number multiplication (Was: Where's the problem ?)

2007-07-05 Thread apfelmus
Philip Armstrong wrote:
 genericLength   :: (Num i) = [b] - i
 genericLength []=  0
 genericLength (_:l) =  1 + genericLength l
 
 So genericLength is lazily building up unevaluated (+) expressions and
 running out of stack space.
 
 Is there a good reason for genericLength to be lazy?

Yes, since addition in  i  may well be lazy.

  data Nat = Zero | Succ Nat

  instance Num Nat where
 Zero + b = b
 (Succ a) + b = Succ (a + b)
 ...

  natLength :: [a] - Nat
  natLength = genericLength

Also, you can turn the foldr into a foldl' with a cleverly chosen data
type like

  data Int' = I Int | Plus Int' Int'

  eval :: Int' - Int
  eval = eval' 0
 where
 eval' (I i) k  = k + i
 eval' (Plus x y) k = eval' y $! eval' x k

  instance Num Int' where
 (+) = Plus
 ...

or in its bare essence

  newtype DiffInt = DI { unDI :: Int - Int }

  instance Num DiffInt where
 (+) f g k = DI $ unDI g $! unDI f k

  evalDI :: DiffInt - Int
  evalDI f = unDI f 0


Regards,
apfelmus

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


[Haskell-cafe] Re: Playing with delimited continuations

2007-07-05 Thread oleg

The ZFS library contains the most up-to-date implementation of the CC
monad and the transformer. I have a few other versions scattered
around, but they are probably not relevant. I found the CC_FrameT.hs
to be the fastest one.

 Is that you can think of normal continuations as delimited
 continuations with a global prompt p0 that denotes the end of the
 computation. You can emulate this using the reader monad to store the
 prompt:

Alternatively, one can use implicit parameters. They are quite handy
in this case.


 So, I suppose my first question is if anyone can see a better way of
 generalizing the types of the control operators to work with the
 arbitrarily nested monad stacks typically used in MTL.

I believe the answer to this question is NO. That means, (delimited)
continuations expose the fundamental limitation of monadic
transformers. Monadic transformation approach imposes the strict
separation of layers. They layers are fixed at compile time and can't
dynamically change. Alas, there are many _practically significant_
circumstances where the layers have to change dynamically, have to
interleave. Our ICFP06 paper discusses this point a bit, and the
accompanying code contains the relevant examples. 
http://okmij.org/ftp/packages/DBplusDC-README.txt
Please see the README file and the file reader.hs in the source code.

When we first realized that monadic transformers had a significant
limitation, we too felt odd. Please see also below.

 First, the prompt module needs to use unsafeCoerce, or something equivalent.
 But, of course, unsafeCoerce feels dirty to me, and it'd be nice if some cool
 type system hackery could be used instead of going around the type system.

Alternatively, if we have reference cells available (STRef or IORef),
then we don't need unsafeCoerce. The whole code is pure Haskell with
no unsafe operations, and is type safe and sound. This outcome is not
an accident: given monadic style, the CC monad and reference cells are
`equivalent'. Given one, we can get the other. Any type system that is
capable of typing reference cells will give us delimited continuations
(provided we have the monadic style so we can deal with the
`stack'). One part of that claim, from multi-prompt delimited
continuations to reference cells, was formulated and proven in the
ICFP06 paper. The converse was formulated in an appendix to the paper,
which was taken out because we ran out of space-time. The proof
was done by construction, which is not generally available (although
the pure OCaml implementation of CC shows how that can be done).

The only drawback of using STRef or IORef to implement CC is that CC
is no longer a transformer (because neither ST nor IO are). That may
not be such a big drawback as the only benefit of CC being transformer
(for us, at least) is that we can lay it out over the IO monad. Well,
actually there is another benefit, of limiting the effects of the
code: even if the CC m code will execute in the IO monad, the code
cannot know that. 

Incidentally, there is actually little need to mix CC with other monad
transformers like reader, writer, RWST, Error, etc. The CC monad
subsumes them all! That is the important theoretical result by
Filinski: delimited continuations can express every expressible monad. 
This has important practical benefits: we can use real names (variables
of the type Prompt) to operate various pieces of state, environment,
errors, etc. We no longer need to count the number of 'lift'. The
overall performance may be better, too: each monadic layer adds at
least one closure. CC monad can implement threads, and I have a hunch
CC monad can implement STM.

 Second is a minor point. There's a sequence datatype in the paper that
 represents the delimited stack:

  data Seq s r a b ...

 Which represents a sequence of frames that take a value of type 'a' to
 a value of type 'b'. The paper mentions that the empty constructor
 should have type 'Seq s r a a', but that it's impossible to do that,
 so they instead have it take a function that provides evidence of the
 equivalence between a and b, using 'id' and a smart constructor to
 have the same effect. But, with GADTs, it's now possible to have a
 constructor with the right type directly, so I did that in my
 implementation.

Have you checked the latest draft of the paper from Amr Sabry's home
page? They might have changed that point. Anyway, there is an
implementation 

 data Seq s r a = PushP (Prompt.Prompt r a) (Seq s r a)
| forall c. PushSeg (s r a c) (Seq s r c)
| forall c. PushCO (a - c) (Seq s r c)

 type SubSeq s r a b = Seq s r b - Seq s r a

that has no EmptyS constructor as you can see. So, the trouble you
have encountered goes away. The authors are aware of that minor
point. The point is truly minor so perhaps it is not bothering
with. If you'd like that code, please check with the authors first,
because it is wholly based on their work.


Re: [Haskell-cafe] A very nontrivial parser

2007-07-05 Thread Malcolm Wallace
Andrew Coppin [EMAIL PROTECTED] wrote:

 My goal is to be able to stack multiple parsers one on top of the
 other  - but be able to *change* the stack half way through parsing if
 needed.
 
 Essentially, I have the stacked function, where if I do
 
   x - stacked foo parser1 bar parser2
   y - parser3
 
 then it runs parser2, but it uses parser1 to transform the data first.

I can't help thinking that all you really want to do is parse the same
data twice, through an intermediate representation.  That only requires
you to feed the result of one parse into a top-level call to a different
parser.  For instance:

  this = do
tmp - parser1
x   - return (runParser parser2 bar tmp)
y   - parser3

  ... = runParser this foo input

In the example, 'parser2' takes a different state type, and a different
source token representation from 'parser1' and 'parser3'.  No fearsome
stack type is needed.  :-)

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


[Haskell-cafe] Re: Lightweight sequent calculus and linear abstractions

2007-07-05 Thread Conor McBride

Hi Oleg

On 5 Jul 2007, at 07:15, [EMAIL PROTECTED] wrote:



Conor McBride has posed an interesting problem:

   implement constructors
 P v  for embedding pure values v
 Ofor holes
 f :$ a   for application, left-associative
   and an interpreting function
 emmental
   such that
 emmental (P (+) :$ (P (*) :$ O :$ P 10) :$ O) 4 2 = 42


I believe one can do better. There is no need for the :$ operation,  
and

there is no need for of lifting non-functional constants.


I was hoping for something of the sort. I'm glad you could oblige.



The following code
demonstrates a more economical notation. The code essentially
implements Hypothetical Reasoning, considering an expression with
holes as an (intuitionistic) sequent. Each hole is one formula in the
antecedent. The formulas in the antecedent are ordered, so our logic
is actually the relevance, substructural intuitionistic logic. The
function emmental takes the form of the Deduction Theorem (and its
implementation is the proof of the theorem).


That's what I had in mind.



The test takes the form


test_McBride = dt ((ih *! (10::Int)) +! ih) 4 2
 where ih = holet (undefined::Int)


and gives the predictable answer.


But perhaps you are cheating a bit...


infixl 6 +!
infixl 7 *!
infixr 5 !:

x +! y = l2 (+) x y
x *! y = l2 (*) x y
x `p` y = l2 (,) x y

x !: y = l2 (:) x y


...with lifting defined per arity. Of course you can use arity-specific
overloading to hide the Ps and :$s, but you haven't given a closed
solution to the general problem. By the way, we should, of course, also
permit holes in function positions...

*Emmental emmental (O :$ P 3) (2 +)
5

...but I don't imagine that's a big deal.

So neither situation is particularly satisfying. I have a noisy but  
general

solution; you have a technique for delivering less noisy solutions in
whatever special cases might be desirable. I wonder if we can somehow
extract the best from both. You've certainly taught me some useful  
tricks!


Many thanks

Conor

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


Re: [Haskell-cafe] System.Exit

2007-07-05 Thread Thomas Conway

FWIW,

I implemented the STM based solution, and it works a treat. It's less
of a hack than the version where I got the child thread to send a
SIGINT. ;-)

T.
--
Dr Thomas Conway
[EMAIL PROTECTED]

Silence is the perfectest herald of joy:
I were but little happy, if I could say how much.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Parsers are monadic?

2007-07-05 Thread Claus Reinke

(b) i like my combinator grammars to be reversible, so that a single
grammar specification can be used for both parsing and
unparsing/pretty-printing.  that means i have to define the
details myself anyway.


the latest such experiment is not necessarily the simplest variant, 


for instance, it explicitly gives semantic functions and their inverses,
which i've found to be useable compromise in practice. but if you 
apply a bit of generic programming to associate an ast node with

its constructor and children (or if you use an untyped representation
of the ast, like 'data AST = Node ConstructorTag [AST]'), with
constructor tags that can be compared for equality, you can avoid 
even that bit of duplication.


also, i should have mentioned that the same idea, of using a single
grammar specification in parse or unparse mode, opens up a 
variety of other application possibilities. i already touched upon

syntax-directed editing (use a zipper combined with i/o to allow
interactive navigation of the ast; associate each type of ast node
with its grammar rule; unparse the current node with its rule to
display it, let the user edit, then parse the input with the rule for
the current node, and continue navigation). 

another interesting option is to use combinator grammars to 
specify dialogue protocols: if one annotates the positions in 
grammar rules where activity switches between dialogue 
partners, such as server and client communicating according 
to some protocol, then both server and client can run the same 
grammar code, in complementary modes, using the switch

points to move from producing to expecting dialogue, and
vice versa. i've attached a silly little example, using which:

   $ runhaskell Dialogue.hs server
   HTTP/1.1 200
   Content-Length: 15
   Content-Type: text/plain
   
   this

   is
   a
   text
   
   $ runhaskell Dialogue.hs server | runhaskell.exe Dialogue.hs  client

   this
   is
   a
   text


as i said, many opportunities, and i've sometimes wondered
why noone else seems to use this technique. perhaps i'll get
around to writing it up some day, after all these years.. 


claus


Dialogue.hs
Description: Binary data
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Playing with delimited continuations

2007-07-05 Thread Dan Doel
On Thursday 05 July 2007, [EMAIL PROTECTED] wrote:
 I believe the answer to this question is NO. That means, (delimited)
 continuations expose the fundamental limitation of monadic
 transformers.

I suppose this is a bit disheartening, but I suppose it's also good to know I 
wasn't totally off track. Closure is nice.

 Our ICFP06 paper discusses this point a bit, and the
 accompanying code contains the relevant examples.
   http://okmij.org/ftp/packages/DBplusDC-README.txt
 Please see the README file and the file reader.hs in the source code.

I stuck this on my reading list during my brief searches a few days ago. I'll 
have to get busy reading it.

 Alternatively, if we have reference cells available (STRef or IORef),
 then we don't need unsafeCoerce. The whole code is pure Haskell with
 no unsafe operations, and is type safe and sound.

Good to know. I suppose ST gives me less of an icky feeling than unsafeCoerce.

 Incidentally, there is actually little need to mix CC with other monad
 transformers like reader, writer, RWST, Error, etc. The CC monad
 subsumes them all!

This had actually crossed my mind, although making CC work more like the rest 
of the monads in MTL, rather than the somewhat more isolated ST seemed like a 
noble goal. Perhaps time would be better spent working out 
analogues/instances of classes using just the CC monad, though, for times 
when you want to use the interfaces (but not necessarily the actual 
transformers, due to the issues above) along with delimited continuations. I 
suppose it's something to think about.

 Have you checked the latest draft of the paper from Amr Sabry's home
 page? They might have changed that point. Anyway, there is an
 implementation

  data Seq s r a = PushP (Prompt.Prompt r a) (Seq s r a)
 
 | forall c. PushSeg (s r a c) (Seq s r c)
 | forall c. PushCO (a - c) (Seq s r c)
 
  type SubSeq s r a b = Seq s r b - Seq s r a

 that has no EmptyS constructor as you can see. So, the trouble you
 have encountered goes away. The authors are aware of that minor
 point. The point is truly minor so perhaps it is not bothering
 with. If you'd like that code, please check with the authors first,
 because it is wholly based on their work.

As a matter of fact, I had two versions of the paper, but neither was the 
latest. The newest version (if it's what I now have) does use GADTs to 
enforce the 'Seq s r a a' type of EmptyS, but more surprisingly than that (to 
me, at least), it no longer has a coercion constructor, as they no longer use 
functions for evidence. Instead, it uses another GADT as the evidence, and 
unsafeCoerce on that. Eliminating PushCO and such altogether seems 
attractive.

Anyhow, thanks for the input, and the pointers to the papers and such (and 
writing so many of them in the first place. :) Incidentally, I really enjoyed 
your Delimited continuations in operating systems paper. Reading that one 
really made things click for me as to how delimited continuations can 
actually show up in real systems, as opposed to just being an esoteric, 
abstract construct).

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


[Haskell-cafe] Profiling and Threading: never the twain shall meet

2007-07-05 Thread Dougal Stanton

Hi Haskellers,

It seems that profiling and threading are not supported at the same
time in GHC6.6. At least, it objects to using both the flags at the
same time, and there's a Trac entry for that issue.

So I just wanted to be sure that I really need threading. I'm passing
text through some filters written in perl, just ordinary command line
programs. I do it like this:


do
  (hin, hout, herr, ph) - runInteractiveProcess cmd args Nothing Nothing
  forkIO $ hPutStr hin content  hClose hin
  out - hGetContents hout
  return (ph, out)


which seems to require threading. If I compile without, it will hang
indefinitely, I presume deadlocked. Is there a way this can be done
without threading?

But it's not a great issue for me if I can't do profiling in this
case. I just wanted to try out the feature, and it seemed worthwhile
checking I was doing this right.

Cheers,

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


Re: [Haskell-cafe] Binary serialization, was Re: Abstraction leak

2007-07-05 Thread Jonathan Cast
On Thursday 05 July 2007, Thomas Conway wrote:
 I was explaining Haskell to a perl/python hacking friend recently and
 characterized things thus:

 Perl is a horrible language with fantastic libraries.
 Haskell is a fantastic language with horrible libraries.

 Actually, many of the libraries that exist for Haskell *are*
 fantastic, it's just that Haskell lacks the *coverage* that Perl or
 Python have.

Can't say I agree.  I've been learning Python, and have been very un-impressed 
so far with its library coverage, which I would rate no better than (in terms 
of the POSIX bindings, worse than) Haskell.

The one thing off the top of my head that Python had was Base64, but that's 20 
lines of Haskell tops.  Aside from that, nothing.

Jonathan Cast
http://sourceforge.net/projects/fid-core
http://sourceforge.net/projects/fid-emacs
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Binary serialization, was Re: Abstraction leak

2007-07-05 Thread Paul Moore

On 05/07/07, Jonathan Cast [EMAIL PROTECTED] wrote:

Can't say I agree.  I've been learning Python, and have been very un-impressed
so far with its library coverage, which I would rate no better than (in terms
of the POSIX bindings, worse than) Haskell.


It probably depends on your perspective. I've found lots of tasks that
would be a simple library call in Python, but which require me to
write the code myself in Haskell. Examples:

* Send an email
* Parse an ini file
* Gzip compress a data stream
* Calculate the MD5 checksum of a file

(Of course, I may just not have found the relevant library - that says
something about discoverability rather than coverage, I guess).

For bindings, Python's Windows bindings (pywin32) are superb, where
Haskell's are minimal and unmaintained. Of course, that won't matter
to you if you use POSIX...


The one thing off the top of my head that Python had was Base64, but that's 20
lines of Haskell tops.  Aside from that, nothing.


But that's 20 lines of code I don't want to write, and more, I don't
know how to write (without looking up the definition of Base64).
Having lots of these seemingly trivial helpers available out of the
box is what library coverage means to me. (And Python does have lots
of these - I don't know how Haskell fares in practice).

I'm not trying to start (or fan) a flamewar, but it's interesting how
different people's perspectives on libraries can be...

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


Re[2]: [Haskell-cafe] Binary serialization, was Re: Abstraction leak

2007-07-05 Thread Bulat Ziganshin
Hello Paul,

Thursday, July 5, 2007, 7:00:46 PM, you wrote:
 * Gzip compress a data stream

zlib

 * Send an email
 * Parse an ini file
 The one thing off the top of my head that Python had was Base64, but that's 
 20

MissingH

 * Calculate the MD5 checksum of a file

crypto


-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]

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


Re: Re[2]: [Haskell-cafe] Binary serialization, was Re: Abstraction leak

2007-07-05 Thread Paul Moore

On 05/07/07, Bulat Ziganshin [EMAIL PROTECTED] wrote:

 * Gzip compress a data stream
zlib

 * Send an email
 * Parse an ini file
 The one thing off the top of my head that Python had was Base64, but that's
MissingH

 * Calculate the MD5 checksum of a file
crypto


Thanks.

The need I had for these is no longer current, but sometime I'll try
an experiment and see how easy it is, on a relatively clean Windows
box with just GHC installed, to grab and use these libraries. (Side
note: with Python, I'm used to 3rd party modules being available as
Windows installer packages - does the concept of an installable binary
for something like MissingH, which I can just install and use, make
sense for a compiled language like Haskell? The build, find I'm
missing a C library, get it, compile it, fix bugs, try again cycle I
used to hit before Python Windows installers became common isn't
something I'd like to repeat...)

As I mentioned in passing, it may well be that the library issue with
Haskell is more of a perception (or maybe organisational) issue than a
technical one...

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


Re: [Haskell-cafe] Binary serialization, was Re: Abstraction leak

2007-07-05 Thread Philip Armstrong

On Thu, Jul 05, 2007 at 09:41:23AM -0700, Dave Bayer wrote:
There are people who claim with a straight face that they migrated to OS X 
primarily to use TextMate


http://www.textmate.com


Presumably you mean http://macromates.com/ ?

Phil

--
http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: Re[2]: [Haskell-cafe] Binary serialization, was Re: Abstraction leak

2007-07-05 Thread Neil Mitchell

Hi

It's not a great experience now, but hopefully things are moving in
the right direction.


- Found crypto 3.0.3 on hackage.
- Tried to build, it depends on NewBinary


Cabal-install is intended to remove this problem, so that you can say
i want crypto and it gets everything that requires.


- Found that on hackage, downloaded and built OK. Lots of scary
warnings about happy, greencard etc, not being found during configure,
but let's go on.


I've complained about these before, although I don't think anyone
considered doing anything about it.


- Installed NewBinary as I didn't know how to make crypto find it
without installing it. I'm a bit nervous, as I don't know how to
*un*install it after I've finished. And it installed to my C drive,
where I'd really rather it went somewhere else. There is probably
documentation on how to do this, but remember, all I really want to do
is to write a tiny program to get the MD5 checksum of a file.


--prefix should put it where you want. What you really want is a
Windows user interface, which is what I want too.


- crypto builds and installs OK. But where are the docs? Not installed
anywhere obvious, not on hackage. Try google.


You can install them with runhaskell Setup haddock, but I have no idea
where they end up. They will be on hackage at some point, with
cross-indexing etc.


- But no simple examples, and the haddoc docs show APIs, but not usage examples!


Complain to the author. I always try and include a manual with at
least one short example of how to use the library to do something
interesting. Unfortunately all these things take time, something that
not everyone has.


I see you've already responded, and we're in broad agreement. So I
won't labour the point. It's an infrastructure issue rather than a
technical one, and it *will* improve. What will be interesting is how
much the generally lousy Windows experience can be improved


Part of the problem is that the number of Windows Haskell developers
is low. Another part of the problem is that some people have scorn and
contempt for Windows. Alas, those things are hard to change.

Thanks

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


Re: [Haskell-cafe] Binary serialization, was Re: Abstraction leak

2007-07-05 Thread Dave Bayer


On Jul 5, 2007, at 8:00 AM, Paul Moore wrote:


It probably depends on your perspective. I've found lots of tasks that
would be a simple library call in Python, but which require me to
write the code myself in Haskell. Examples:

* Calculate the MD5 checksum of a file


How's this, only one line is specific to your problem:


import System.Process
import IO

doShell :: String - IO String
doShell cmd = do
(_,out,_,_) - runInteractiveCommand cmd
hGetContents out

main :: IO ()
main = do
md5 - doShell md5 -q md5.hs
putStrLn md5


It's not like you'll be kicked out of the tree house for leaving the  
Haskell world to get things done. For example, ghostscript and pdf2ps  
are well-supported open source tools for converting PS to PDF, that  
can be called from most languages. What's the deal with everyone  
rewriting PDF handling in their pet language, when it's so much  
easier to generate Postscript? I'd call that Balkanization; if I were  
managing a software group, I'd never let that happen.


The true problem isn't adequate libraries in each language, it's  
interoperability so great open-source tools can get written once and  
then be supported by a cast of thousands.


There are people who claim with a straight face that they migrated to  
OS X primarily to use TextMate


http://www.textmate.com

which is a GUI editor getting Emacs-like buzz, making Emacs seem by  
comparison like your grandfather's razor. It's as much a text-based  
operating system as an editor, and the whole thing is glued together  
with hundreds of snippets of code one can hack, written in every  
scripting language imaginable. Polyglots feel right at home...


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


Re: Re[2]: [Haskell-cafe] Binary serialization, was Re: Abstraction leak

2007-07-05 Thread Paul Moore

On 05/07/07, Paul Moore [EMAIL PROTECTED] wrote:

The need I had for these is no longer current, but sometime I'll try
an experiment and see how easy it is, on a relatively clean Windows
box with just GHC installed, to grab and use these libraries.


Just for fun I had a go with crypto:

- Found crypto 3.0.3 on hackage.
- Tried to build, it depends on NewBinary
- Found that on hackage, downloaded and built OK. Lots of scary
warnings about happy, greencard etc, not being found during configure,
but let's go on.
- Installed NewBinary as I didn't know how to make crypto find it
without installing it. I'm a bit nervous, as I don't know how to
*un*install it after I've finished. And it installed to my C drive,
where I'd really rather it went somewhere else. There is probably
documentation on how to do this, but remember, all I really want to do
is to write a tiny program to get the MD5 checksum of a file.

Ah, well. Carry on.

- crypto builds and installs OK. But where are the docs? Not installed
anywhere obvious, not on hackage. Try google.
- Found the crypto website, but aargh! It looks like 3.0.3 is out of
date and there's a 4.x available. Never mind, that's not likely to
have changed.
- But no simple examples, and the haddoc docs show APIs, but not usage examples!

Going for the obvious approach:

import System.IO
import Data.Digest.MD5

main = do
   h - openBinaryFile md5.hs ReadMode
   s - hGetContents h
   hClose h
   md5 - hash s

No surprise, this doesn't work. After all, hash wants [Octet], not String.

OK, I know this is now getting beyond library availability. But it
doesn't compare well to Python's I want an md5 checksum of a file -
check the docs, there's a library function built in, use it, no
problems.

I see you've already responded, and we're in broad agreement. So I
won't labour the point. It's an infrastructure issue rather than a
technical one, and it *will* improve. What will be interesting is how
much the generally lousy Windows experience can be improved - as
Duncan points out, installing development libraries on Windows,
whether Haskell or C, is a hugely irritating pain. If no-one has found
a good answer for C in all these years, it would be great if Haskell
could even do slightly better :-)

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


Re: Re[2]: [Haskell-cafe] Binary serialization, was Re: Abstraction leak

2007-07-05 Thread Duncan Coutts
On Thu, 2007-07-05 at 17:07 +0100, Paul Moore wrote:
 On 05/07/07, Bulat Ziganshin [EMAIL PROTECTED] wrote:
   * Gzip compress a data stream
  zlib
 
   * Send an email
   * Parse an ini file
   The one thing off the top of my head that Python had was Base64, but 
   that's
  MissingH
 
   * Calculate the MD5 checksum of a file
  crypto
 
 Thanks.
 
 The need I had for these is no longer current, but sometime I'll try
 an experiment and see how easy it is, on a relatively clean Windows
 box with just GHC installed, to grab and use these libraries.

Just to warn you, a lot of haskell packages that bind to C libs are much
harder to get working on Windows, the zlib package for example.

This is because on all other platforms zlib comes with the system and is
installed in a location where any application can link to it. On Windows
there is no equivalent of /usr/lib you cannot easily install a C lib
somewhere that it can be used by any .exe on the system. 

To make things easier yuo could avoid using -fvia-C and then at least
the zlib header files would not need to be installed, but to run a
program that uses the zlib package you'd still have to copy the zlib.dll
into the same dir as your .exe.

There is a mechanism in newer versions of Windows that allows
installing .dlls systemwide where any .exe can use them, however ghc and
the gcc toolchain do not support them yet. It requires embeding xml
manifests into the .dll and .exe files and you have to be the admin user
to install one of these systemwide .dll things. It's all a bit of a
pain.

Duncan

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


Re[4]: [Haskell-cafe] Binary serialization, was Re: Abstraction leak

2007-07-05 Thread Bulat Ziganshin
Hello Paul,

Thursday, July 5, 2007, 8:07:34 PM, you wrote:

 note: with Python, I'm used to 3rd party modules being available as
 Windows installer packages - does the concept of an installable binary
 for something like MissingH, which I can just install and use, make
 sense for a compiled language like Haskell? The build, find I'm

all cabalized libraries are installed using the same commands:

runghc setup.hs configure
runghc setup.hs build
runghc setup.hs install

after this, you just import modules you need in your program and
when you build your program, ghc automatically links in all the
library functions you used

 As I mentioned in passing, it may well be that the library issue with
 Haskell is more of a perception (or maybe organisational) issue than a
 technical one...

the problem exists and for me, it's most important Haskell
insfrastructure problem. but things you are mentioned are already
implemented

i personally implemented several libs required for my own program; and
still miss ease-to-use and maintained GUI library


-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]

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


Re: [Haskell-cafe] Binary serialization, was Re: Abstraction leak

2007-07-05 Thread Paul Moore

On 05/07/07, Dave Bayer [EMAIL PROTECTED] wrote:

How's this, only one line is specific to your problem:

[...]

 md5 - doShell md5 -q md5.hs


Doesn't work on my (Windows) PC, where I have no md5 command
available. While I agree in theory with the idea of combining focused
tools, it's a potential portability nightmare, particularly on Windows
where decent command line tools are almost non-existent on a clean
install.

You're changing the problem from finding a Haskell library (which only
needs to be installed on the development machine at compile time) to
finding a 3rd party utility, which has to be installed at runtime on
any machine using the compiled Haskell program. Not a good trade-off.

And I'm not going to get into Windows/Linux arguments... :-)

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


Re: Re[2]: [Haskell-cafe] Binary serialization, was Re: Abstraction leak

2007-07-05 Thread Paul Moore

On 05/07/07, Neil Mitchell [EMAIL PROTECTED] wrote:

 - But no simple examples, and the haddoc docs show APIs, but not usage 
examples!

Complain to the author.


Yes, that's completely unrelated to library availability issues. I got
off the topic, in all my ranting. Sorry.


Part of the problem is that the number of Windows Haskell developers
is low. Another part of the problem is that some people have scorn and
contempt for Windows. Alas, those things are hard to change.


Agreed. I'm extremely grateful for all the contributions people *do*
make, even where they don't fit my environment as well as I might
like.

Anyway, I'm running out of time for today, so I'll leave this thread
now. Thanks to all for some interesting comments and pointers!

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


Re: Re[2]: [Haskell-cafe] Binary serialization, was Re: Abstraction leak

2007-07-05 Thread Duncan Coutts
On Thu, 2007-07-05 at 17:39 +0100, Paul Moore wrote:
 I see you've already responded, and we're in broad agreement. So I
 won't labour the point. It's an infrastructure issue rather than a
 technical one, and it *will* improve. What will be interesting is how
 much the generally lousy Windows experience can be improved -

We have this slightly odd problem where half our user base use Windows
(according to the GHC user survey) but almost every active developer
uses Linux or OSX (or a few other BSD/Unix OSs). So we could enormously
improve the Windows user experience (and a few heroes work hard on doing
just that) but basically there just aren't enough developers who use
windows to give it a satisfactory level of support.

This is of course a slightly circular problem, since using/developing
Haskell on Windows is a pain, developers avoids it and so there are not
enough developers irritated by how difficult it is to motivate
developers to fix it!

Duncan

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


Re: [Haskell-cafe] A very nontrivial parser

2007-07-05 Thread Andrew Coppin

Malcolm Wallace wrote:

I can't help thinking that all you really want to do is parse the same
data twice, through an intermediate representation.  That only requires
you to feed the result of one parse into a top-level call to a different
parser.  For instance:

  this = do
tmp - parser1
x   - return (runParser parser2 bar tmp)
y   - parser3

  ... = runParser this foo input

In the example, 'parser2' takes a different state type, and a different
source token representation from 'parser1' and 'parser3'.  No fearsome
stack type is needed.  :-)
  


For the Nth time... The amount of data processed by parser1 needs to 
depend on the amount of data processed by parser2. (The amount of data 
output by each parser is very nontrivially related to the amount of data 
consumed.)


How do you propose to pull that off?

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


Re: [Haskell-cafe] A very nontrivial parser

2007-07-05 Thread Andrew Coppin

Jonathan Cast wrote:

On Wednesday 04 July 2007, Andrew Coppin wrote:
  

Anybody have a solution to this?



newtype Parser state x y
  = Parser (forall src. Source src = (state, src x) - (state, src x, y))
  


...OK, anybody have a solution that works in Haskell 98?


Definition of monad functions, etc, works exactly as for your version.


Not so.

In fact, doing this causes all mannar of malfunctions. First I get lots 
of messages of the form


Cannot (yet) use update syntax on non-Haskell98 types.

Then I get lots of

Cannot use function 'foo' as a selector.

And then I get

My brain has exploded. I can't handle pattern bindings in 
existentially-quantified type constructors.


(?!)

And after that I get

Type variable 'bar' escapes pattern binding.

And finally, after I correct all of those, I get an error saying that 
the compiler can't match [the hidden type variable] against [some 
suitable type for that variable]. And in a pattern of all things! 
(Surely if it's not the right type at runtime, it should generate an 
exception, just like if you use the wrong constructor...?)


In all, the whole thing just malfunctions horribly and I can get no 
useful work done! _


So my next plan was to write the code as normal, and then create a 
front-end module which hides all the messy types. But then I just get 
a whole bunch of escaping type variable errors again.


Basically everything I tried make the code drastically more complicated, 
and even *then* certain parts of it (most especially the stack function) 
wouldn't compile.


So *neeer* :-P

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


Re: Re[2]: [Haskell-cafe] Binary serialization, was Re: Abstraction leak

2007-07-05 Thread Ian Lynagh
On Thu, Jul 05, 2007 at 06:08:45PM +0100, Duncan Coutts wrote:
 On Thu, 2007-07-05 at 17:51 +0100, Neil Mitchell wrote:
  
   - Found that on hackage, downloaded and built OK. Lots of scary
   warnings about happy, greencard etc, not being found during configure,
   but let's go on.
  
  I've complained about these before, although I don't think anyone
  considered doing anything about it.
 
 We know what needs to change, but it's not a trivial change.

If anyone's interested, this is the Cabal bug for it:
http://hackage.haskell.org/trac/hackage/ticket/132


Thanks
Ian

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


Re: [Haskell-cafe] Re: Lightweight sequent calculus and linear abstractions

2007-07-05 Thread Conor McBride


On 5 Jul 2007, at 18:35, Chung-chieh Shan wrote:

[EMAIL PROTECTED] wrote in article  
[EMAIL PROTECTED] in  
gmane.comp.lang.haskell.cafe:

Conor McBride has posed an interesting problem:

   implement constructors
 P v  for embedding pure values v
 Ofor holes
 f :$ a   for application, left-associative
   and an interpreting function
 emmental
   such that
 emmental (P (+) :$ (P (*) :$ O :$ P 10) :$ O) 4 2 = 42


Hrm!  I don't see the original message where the problem was posed,  
but

it is indeed interesting.  Here is my solution, but I don't need P,
O, and :$ to be constructors, so I rename them to p, o, and
$:, respectively:

emmental m = m id
p x k = k x
o k = k
(m $: n) k = m (\f - n (\x - k (f x)))

infixl 0 $:
test = emmental (p (+) $: (p (*) $: o $: p 10) $: o) 4 2 -- 42



Very nice!

Thanks

Conor

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


[Haskell-cafe] Re: Lightweight sequent calculus and linear abstractions

2007-07-05 Thread Chung-chieh Shan
[EMAIL PROTECTED] wrote in article [EMAIL PROTECTED] in 
gmane.comp.lang.haskell.cafe:
 Conor McBride has posed an interesting problem:
 implement constructors
   P v  for embedding pure values v
   Ofor holes
   f :$ a   for application, left-associative
 and an interpreting function
   emmental
 such that
   emmental (P (+) :$ (P (*) :$ O :$ P 10) :$ O) 4 2 = 42

Hrm!  I don't see the original message where the problem was posed, but
it is indeed interesting.  Here is my solution, but I don't need P,
O, and :$ to be constructors, so I rename them to p, o, and
$:, respectively:

emmental m = m id
p x k = k x
o k = k
(m $: n) k = m (\f - n (\x - k (f x)))

infixl 0 $:
test = emmental (p (+) $: (p (*) $: o $: p 10) $: o) 4 2 -- 42

All credit is due to Danvy and Filinski (DIKU TR 89/12, Section 3.4;
later Danvy's functional unparsing paper, JFP 8(6)).  One way to
understand this code is that o is like the word what in a language
like Mandarin (shenme) or Japanese (dare) that does not move any
wh-word to the boundary of a clause.  In Japanese, emmental would
correspond to the -ka that marks the scope of a question and awaits
an answer (in this case the numbers 4 and 2).  Or, we have control
inversion: the argument to emmental is a sandboxed user process that
occasionally requests input.

-- 
Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig
Gordon Brown's special advisors:
www.christianaid.org.uk/stoppoverty/climatechange/stories/special_advisers.aspx

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


Re: [Haskell-cafe] Profiling and Threading: never the twain shall meet

2007-07-05 Thread Albert Y. C. Lai

Dougal Stanton wrote:

do
  (hin, hout, herr, ph) - runInteractiveProcess cmd args Nothing Nothing
  forkIO $ hPutStr hin content  hClose hin
  out - hGetContents hout
  return (ph, out)


which seems to require threading. If I compile without, it will hang
indefinitely, I presume deadlocked. Is there a way this can be done
without threading?


With much sweat, you could write your own timed polling loop and avoid 
threads, using hPutBufNonBlocking and hGetBufNonBlocking. I don't 
recommend it, except for fun or self-torture.

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


Re: [Haskell-cafe] A very nontrivial parser

2007-07-05 Thread Jonathan Cast
On Thursday 05 July 2007, Andrew Coppin wrote:
 Jonathan Cast wrote:
  On Wednesday 04 July 2007, Andrew Coppin wrote:
  Anybody have a solution to this?
 
  newtype Parser state x y
= Parser (forall src. Source src = (state, src x) - (state, src x,
  y))

 ...OK, anybody have a solution that works in Haskell 98?

Rank-2 types are perhaps /the/ most common, widely accepted extension to 
Haskell 98, after the approved addendum for FFI and the draft addendum for 
hierarchical modules.  I would really be concerned about using them (it's 
certainly not like they're going to just disappear on you one day, like say 
functional dependencies almost certainly will).  But that's just me.

  Definition of monad functions, etc, works exactly as for your version.

 Not so.

 In fact, doing this causes all mannar of malfunctions. First I get lots
 of messages of the form

 Cannot (yet) use update syntax on non-Haskell98 types.

 Then I get lots of

 Cannot use function 'foo' as a selector.

 And then I get

 My brain has exploded. I can't handle pattern bindings in
 existentially-quantified type constructors.

 (?!)

 And after that I get

 Type variable 'bar' escapes pattern binding.

 And finally, after I correct all of those, I get an error saying that
 the compiler can't match [the hidden type variable] against [some
 suitable type for that variable]. And in a pattern of all things!
 (Surely if it's not the right type at runtime, it should generate an
 exception, just like if you use the wrong constructor...?)

Just a side point but: how would it know?  Leaving aside the 
dictionary-passing used for type classes, Haskell has (and has always had) a 
type-erasure semantics, which rules out runtime type errors.

 In all, the whole thing just malfunctions horribly and I can get no
 useful work done! _

 So my next plan was to write the code as normal, and then create a
 front-end module which hides all the messy types. But then I just get
 a whole bunch of escaping type variable errors again.

 Basically everything I tried make the code drastically more complicated,
 and even *then* certain parts of it (most especially the stack function)
 wouldn't compile.

 So *neeer* :-P

My first thought is that surely you must have said

newtype Parser state x y
  = forall src. Source src = Parser ((state, src x) - (state, src x, y))

when you meant

newtype Parser state x y
  = Parser (forall src. Source src = (state, src x) - (state, src x, y))

The relative order of the constructor name and the forall is very important!  
If you got the answer right, I can't see why you'd be getting unmistakable 
existential-type errors; there are no existential quantifiers in my proposal.  
But I'll try to implement it myself and see what I get.

Jonathan Cast
http://sourceforge.net/projects/fid-core
http://sourceforge.net/projects/fid-emacs
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] A very nontrivial parser

2007-07-05 Thread Jonathan Cast
Andrew:

By the way, could you share your definition of Stack with us?  It isn't at all 
clear to me how stacked actually decides to terminate the underlying parser.

Jonathan Cast
http://sourceforge.net/projects/fid-core
http://sourceforge.net/projects/fid-emacs
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] A very nontrivial parser

2007-07-05 Thread Andrew Coppin

Jonathan Cast wrote:

On Thursday 05 July 2007, Andrew Coppin wrote:
  

...OK, anybody have a solution that works in Haskell 98?



Rank-2 types are perhaps /the/ most common, widely accepted extension to 
Haskell 98, after the approved addendum for FFI and the draft addendum for 
hierarchical modules.  I would really be concerned about using them (it's 
certainly not like they're going to just disappear on you one day, like say 
functional dependencies almost certainly will).  But that's just me.
  


Personally, I just try to avoid *all* language extensions - mainly 
because most of them are utterly incomprehensible. (But then, perhaps 
that's just because they all cover extremely rare edge cases?)


MPTCs and ATs look useful. The rest... hmm. If I ever figure out what 
they do, maybe I can comment.



And finally, after I correct all of those, I get an error saying that
the compiler can't match [the hidden type variable] against [some
suitable type for that variable]. And in a pattern of all things!
(Surely if it's not the right type at runtime, it should generate an
exception, just like if you use the wrong constructor...?)



Just a side point but: how would it know?  Leaving aside the 
dictionary-passing used for type classes, Haskell has (and has always had) a 
type-erasure semantics, which rules out runtime type errors.
  


Usually if you have something like

 let (Foo x) = process x y z

and it turns out that the 'process' function returns another 
constructor, you get an error. Well you'd expect the same thing to 
happen if the result type happens to be a 'hidden' type. But apparently 
not...



So *neeer* :-P



My first thought is that surely you must have said

newtype Parser state x y
  = forall src. Source src = Parser ((state, src x) - (state, src x, y))

when you meant

newtype Parser state x y
  = Parser (forall src. Source src = (state, src x) - (state, src x, y))

The relative order of the constructor name and the forall is very important!  
  


Care to explain what's different about these apparently identical 
declarations?


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


Re: [Haskell-cafe] A very nontrivial parser

2007-07-05 Thread Andrew Coppin

Jonathan Cast wrote:

Andrew:

By the way, could you share your definition of Stack with us?  It isn't at all 
clear to me how stacked actually decides to terminate the underlying parser.
  


Yeah, I'll post the complete source here in a little while. I think 
that's probably the only way anybody is going to be able to help me 
effectively...



(Netiquette: Is 200 lines too big to past in the body of an email?)

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


Re: [Haskell-cafe] Binary serialization, was Re: Abstraction leak

2007-07-05 Thread Dave Bayer

On Jul 5, 2007, at 9:52 AM, Paul Moore wrote:


You're changing the problem from finding a Haskell library (which only
needs to be installed on the development machine at compile time) to
finding a 3rd party utility, which has to be installed at runtime

...

Not a good trade-off.


The intersection of Linux and Mac OS X is a pretty amazing standard   
library, that beats any single scripting language.


I'd forgotten how dismal Windows is, sorry. Still, if you stick to  
non-GPL'd licenses, there's no way to build single file deliverables?  
I'd think someone would have written Unix as a static library, the  
way e.g. many languages can be embedded in apps. Then only you would  
have to maintain the Unix tools you want to use, and you'd be done.  
If no one has, someone who cares about Windows should. Unix rocks.


On Jul 5, 2007, at 9:54 AM, Philip Armstrong wrote:

Presumably you mean http://macromates.com/ ?


Yup. Sorry.

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


Re[2]: [Haskell-cafe] A very nontrivial parser

2007-07-05 Thread Miguel Mitrofanov
AC For the Nth time... The amount of data processed by parser1 needs
AC to depend on the amount of data processed by parser2. (The amount
AC of data output by each parser is very nontrivially related to the
AC amount of data consumed.)

What about lazyness? Let parser1 process ALL the data and return
chunks of output paired with the amount of data read; then, parser2
have to return it's result paired with the amount of data read, known
from parser1, allowing parser3 to know where to start. It doesn't
matter that parser1 wouldn't recognize the rest of data, since it
wouldn't be fed with it due to lazyness.

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


[Haskell-cafe] Binary serialization, was Re: Abstraction leak

2007-07-05 Thread Dominic Steinitz
 
 (Bonus points for being able to parse ASN.1 and generate appropriate
 Haskell datatypes  serialization primitives automatically :-) )
 
 I think there's at least an ASN.1 definition in the crypto library.
 Dominic might be able to enlighten us on that.
 

No bonus points I'm afraid. There is an embryonic ASN.1 library here

http://hackage.haskell.org/cgi-bin/hackage-scripts/package/ASN1-0.0.1

You can take an ASN.1 definition such as

FooBar {1 2 0 0 6 1} DEFINITIONS ::=
   BEGIN
   Journey ::= SEQUENCE {
  origin IA5String,
  stop1 [0] IA5String OPTIONAL,
  stop2 [1] IA5String OPTIONAL,
  destination IA5String
   }
   Odyssey ::= SEQUENCE {
  start Journey,
  trip1 [0] Journey OPTIONAL,
  trip2 [1] Journey OPTIONAL,
  trip3 [2] Journey OPTIONAL,
  end Journey
   }
   END

And then create abstract Haskell representations of the ASN.1 types

journey =
Journey ::=
 AbsSeq Universal 16 Implicit [
  Regular (Just origin::
 (Nothing :@: absIA5String)),
  Optional (Just stop1::
 (Just 0   :@: absIA5String)),
  Optional (Just stop2::
 (Just 1   :@: absIA5String)),
  Regular (Just destination ::
 (Nothing :@: absIA5String))
  ]

odyssey =
   Odyssey ::=
  AbsSeq Universal 16 Implicit [
  Regular (Just start::  (Nothing :@: journey)),
  Optional (Just trip1   ::  (Just 0  :@: journey)),
  Optional (Just trip2   ::  (Just 1  :@: journey)),
  Optional (Just trip3   ::  (Just 2  :@: journey)),
  Regular (Just end  ::  (Nothing :@: journey))
  ]

The library then allows you to decode BER representations of these
types. It's good enough to decode X.509 identity and attribute certificates.

There's no encoding routines currently as I didn't need them.

I'll try and make some documentation more easily available if I get time
at the weekend.

I'm working on PER at the moment both encoding and decoding using GADTs.
I will extend it at some point for BER but that won't be for some time.

I thought I read that someone was working on parsing ASN.1 so I'll try
and follow that up (again it will have to be at the weekend).

Dominic.



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


Re: [Haskell-cafe] A very nontrivial parser [Source code]

2007-07-05 Thread Andrew Coppin

-- This is probably line-wrapped horribly...



module Process
   (
 Source (..),
 PState (), start,
 Process (run),
 get_state, set_state, alt_state,
 get, eof,
 pure, count, many,
 stack
   )
 where



class Source src where
 empty :: src x - Bool
 fetch :: src x - (x, src x)

instance Source [] where
 empty = null
 fetch xs = (head xs, tail xs)



data PState st src x = PState {state :: st, source :: src x}

start :: (Source src) = st - src x - PState st src x
start = PState



data Process st src x y = Process {run :: PState st src x - (y, PState 
st src x)}


instance (Source src) = Monad (Process st src x) where
 return x = Process (\ps - (x, ps))
 p =  f = Process (\ps - let (y, xs) = run p ps in run (f y) xs)

get_state :: Process st src x st
get_state = Process(\ps - (state ps, ps))

set_state :: st - Process st src x ()
set_state st = Process (\ps - ((), ps {state = st}))

alt_state :: (Source src) = (st - st) - Process st src x ()
alt_state f = do
 st - get_state
 set_state (f st)

get :: (Source src) = Process st src x x
get = Process (\ps - let (x,xs) = fetch (source ps) in (x, ps {source = 
xs}))


eof :: (Source src) = Process st src x Bool
eof = Process (\ps - (empty (source ps), ps))



pure :: (Source src) = (x - y) - Process st src x y
pure f = do
 x - get
 return (f x)

count :: (Source src, Integral n) = n - Process st src x y - Process 
st src x [y]

count 0 _ = return []
count n p = do
 y  - p
 ys - count (n-1) p
 return (y:ys)

many :: (Source src) = Process st src x y - Process st src x [y]
many p = do
 end - eof
 if end
   then return []
   else do
 y  - p
 ys - many p
 return (y:ys)




data Stack st src x y = Stack {pstate :: PState st src x, pro :: Process 
st src x [y], buffer :: [y]}


instance (Source src) = Source (Stack st src x) where
 empty stack = empty $ source $ pstate stack
 fetch stack
   | empty (buffer stack) = let (ys,xs) = run (pro stack) (pstate 
stack) in fetch (stack {pstate = xs, buffer = ys})
   | otherwise= let (y, ys) = fetch (buffer 
stack)   in (y, stack {buffer = ys})


stack :: (Source src0) = st0 - Process st0 src0 x [y] - st1 - 
Process st1 (Stack st0 src0 x) y z - Process st9 src0 x z

stack st0 p0 st1 p1 =
 Process
   (\ps -
 let
   ps0  = PState {state = st0, source = source ps}
   ps1  = PState {state = st1, source = src1}
   src1 = Stack  {pstate = ps0, pro = p0, buffer = []}
   (z, ys) = run p1 ps1
 in (z, ps {source = source $ pstate $ source ys})
   )


-- If you want something to test with...

module AlgoRLE where

import Data.List
import Process

encodeRLE :: (Eq x, Integral n) = [x] - [(n,x)]
encodeRLE = map (\xs - (genericLength xs, head xs)) . group

decodeRLE :: (Integral n) = [(n,x)] - [x]
decodeRLE = concatMap (uncurry genericReplicate)


encodeRLEb :: (Integral x) = [x] - [x]
encodeRLEb = concatMap work . encodeRLE
 where
   work (1,0)= [0,0]
   work (n,0)= [0,n-1,0]
   work (n,x)
 | n   3= [0,n-1,x]
 | otherwise = genericReplicate n x

decodeRLEb :: (Integral x) = [x] - [x]
decodeRLEb = concat . fst . run (many decodeRLEb1) . start ()

decodeRLEb1 :: (Source src, Integral x) = Process st src x [x]
decodeRLEb1 = do
 v - get
 if v == 0
   then do
 n - get
 if n == 0
   then return [0,0]
   else do
 x - get
 return $ genericReplicate (n+1) x
   else return [v]

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


Re: [Haskell-cafe] A very nontrivial parser

2007-07-05 Thread Jonathan Cast
On Thursday 05 July 2007, Andrew Coppin wrote:
 Jonathan Cast wrote:
  On Thursday 05 July 2007, Andrew Coppin wrote:
  ...OK, anybody have a solution that works in Haskell 98?
 
  Rank-2 types are perhaps /the/ most common, widely accepted extension to
  Haskell 98, after the approved addendum for FFI and the draft addendum
  for hierarchical modules.  I would really be concerned about using them
  (it's certainly not like they're going to just disappear on you one day,
  like say functional dependencies almost certainly will).  But that's just
  me.

 Personally, I just try to avoid *all* language extensions - mainly
 because most of them are utterly incomprehensible.

Ah, there's your problem :)

 (But then, perhaps 
 that's just because they all cover extremely rare edge cases?)

I wouldn't call rank-2 types extremely rare . . .

snip

  So *neeer* :-P
 
  My first thought is that surely you must have said
 
  newtype Parser state x y
= forall src. Source src = Parser ((state, src x) - (state, src x,
  y))
 
  when you meant
 
  newtype Parser state x y
= Parser (forall src. Source src = (state, src x) - (state, src x,
  y))
 
  The relative order of the constructor name and the forall is very
  important!

 Care to explain what's different about these apparently identical
 declarations?

Sure.  Given

newtype Parser0 state x y
  = forall src. Source src = Parser0 ((state, src x) - (state, src x, y))

we get

Parser0 :: forall src. Source src
= ((state, src x) - (state, src x, y)) - Parser0 state x y

which type assignment is isomorphic to (note: not legal Haskell!)

Parser0 :: (exists src. Source src = (state, src x) - (state, src x, y))
- Parser0 state x y

Given

newtype Parser1 state x y
  = Parser1 (forall src. Source src = (state, src x) - (state, src x, y))

we get

Parser1 :: (forall src. Source src = (state, src x) - (state, src x, y))
- Parser state x y

The key difference is in the quantifier in the type of the constructor's 
argument.  The exists quantifier (on types) is a tupling operator; Parser0 
takes three arguments: a type (elided at run time!), an instance for the 
Source class (not elided at run time!), and a function implementing the 
parser.

The forall quantifier is a function-forming operator; Parser1 takes one 
argument, which is a function on a type (elided at run time!) and an instance 
for the Source class (not elided at run time!), yielding a function 
implementing the parser.

Using a (thoroughly invalid Haskell) record syntax, we could write the two 
versions

Parser0 :: { type src :: *,
 dict :: Source src,
 fun :: (state, src x) - (state, src x, y)}
- Parser0 state x y

Parser1 :: ({ type src :: *, dict :: Source src, input :: (state, src x)} -
(state, src x, y))
- Parser1 state x y

which may make the distinction a bit clearer (or not).

Jonathan Cast
http://sourceforge.net/projects/fid-core
http://sourceforge.net/projects/fid-emacs
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Sparse documentation

2007-07-05 Thread Ian Lynagh

Hi Andrew,

On Wed, Jul 04, 2007 at 07:26:48PM +0100, Andrew Coppin wrote:
 
 Writing documentation for libraries is one way in which ordinary 
 Haskell users can really contribute to the Haskell community. It’s not 
 hard to do (grab the Darcs repo, type away), and it’s widely appreciated.
 
 How exactly do I get started?
 
 (Obviously I can't write the documentation for the monad transformers - 
 I don't know how they work yet! But I could have a go at splicing all 
 the Parsec goodness into the Haddoc pages...)

Get the latest source:

darcs get http://darcs.haskell.org/packages/parsec
cd parsec

Build the Cabal Setup program and configure the package:

ghc --make Setup
./Setup configure

Then actually update the documentation, in Text/ParserCombinators/...

Now run haddock:

./Setup haddock

and check that it looks reasonable. Open dist/doc/html/index.html in
your web browser and follow the relevant links.

It's probably also a good idea to check you haven't broken the code by
accident, i.e. test that it still builds:

./Setup build

If you are happy then record and send the patch:

darcs record
darcs send




If you think that the patch might be at all contentious then you should
follow the library submissions procedure instead of the last step:

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

but for just adding brief haddock docs that's probably overkill.




Thanks
Ian

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


Re: [Haskell-cafe] A very nontrivial parser [Source code]

2007-07-05 Thread Jonathan Cast
On Thursday 05 July 2007, Andrew Coppin wrote:
snip

This version works (I think).  Also, using this syntax may make the 
distinction between existential constructors and rank-2 constructors a little 
clearer.

*AlgoRLE run decodeRLEb1 $ start () $ encodeRLEb [1, 2, 3]
([1],PState {state = (), source = [2,3]})

--- Process.hs ---

{-# LANGUAGE Rank2Types #-}

module Process
(
  Source (..),
  PState (), start,
  Process (run),
  get_state, set_state, alt_state,
  get, eof,
  pure, count, many,
  stack
)
  where

class Source src where
  empty :: src x - Bool
  fetch :: src x - (x, src x)

instance Source [] where
  empty = null
  fetch xs = (head xs, tail xs)

data PState st src x = PState {state :: st, source :: src x}
  deriving (Eq, Ord, Show)

start :: (Source src) = st - src x - PState st src x
start = PState

data Process st x y
  = Process {run :: forall src. Source src = PState st src x -
(y, PState st src x)}

instance Monad (Process st x) where
  return x = Process (\ps - (x, ps))
  p =  f = Process (\ps - let (y, xs) = run p ps in run (f y) xs)

get_state :: Process st x st
get_state = Process(\ps - (state ps, ps))

set_state :: st - Process st x ()
set_state st = Process (\ps - ((), ps {state = st}))

alt_state :: (st - st) - Process st x ()
alt_state f = do
  st - get_state
  set_state (f st)

get :: Process st x x
get = Process (\ps - let (x,xs) = fetch (source ps)
  in (x, ps {source = xs}))

eof :: Process st x Bool
eof = Process (\ps - (empty (source ps), ps))



pure :: (x - y) - Process st x y
pure f = do
  x - get
  return (f x)

count :: (Integral n) = n - Process st x y - Process st x [y]
count 0 _ = return []
count n p = do
  y  - p
  ys - count (n-1) p
  return (y:ys)

many :: Process st x y - Process st x [y]
many p = do
  end - eof
  if end
then return []
else do
  y  - p
  ys - many p
  return (y:ys)

data Stack st src x y = Stack {
  pstate :: PState st src x,
  pro :: Process st x [y], buffer :: [y]}

instance (Source src) = Source (Stack st src x) where
  empty stack = empty $ source $ pstate stack
  fetch stack
| empty (buffer stack) = let (ys,xs) = run (pro stack) (pstate stack)
 in fetch (stack {pstate = xs, buffer = ys})
| otherwise= let (y, ys) = fetch (buffer stack)
 in (y, stack {buffer = ys})

stack :: st0 - Process st0 x [y] - st1 - Process st1 y z - Process st9 x z
stack st0 p0 st1 p1 =
  Process
(\ps -
  let
ps0  = PState {state = st0, source = source ps}
ps1  = PState {state = st1, source = src1}
src1 = Stack  {pstate = ps0, pro = p0, buffer = []}
(z, ys) = run p1 ps1
  in (z, ps {source = source $ pstate $ source ys})
)

--- AlgoRLE.hs ---

module AlgoRLE where

import Data.List
import Process

encodeRLE :: (Eq x, Integral n) = [x] - [(n,x)]
encodeRLE = map (\xs - (genericLength xs, head xs)) . group

decodeRLE :: (Integral n) = [(n,x)] - [x]
decodeRLE = concatMap (uncurry genericReplicate)


encodeRLEb :: (Integral x) = [x] - [x]
encodeRLEb = concatMap work . encodeRLE
  where
work (1,0)= [0,0]
work (n,0)= [0,n-1,0]
work (n,x)
  | n   3= [0,n-1,x]
  | otherwise = genericReplicate n x

decodeRLEb :: (Integral x) = [x] - [x]
decodeRLEb = concat . fst . run (many decodeRLEb1) . start ()

decodeRLEb1 :: (Integral x) = Process st x [x]
decodeRLEb1 = do
  v - get
  if v == 0
then do
  n - get
  if n == 0
then return [0,0]
else do
  x - get
  return $ genericReplicate (n+1) x
else return [v]

Jonathan Cast
http://sourceforge.net/projects/fid-core
http://sourceforge.net/projects/fid-emacs
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] interrupting an accept()ing thread

2007-07-05 Thread Lukas Mai
Hello, cafe!

I have the following code (paraphrased):

...
forkIO spin
...
spin = do
(t, _) - accept s   -- (*)
forkIO $ dealWith t  -- (**)
spin

My problem is that I want to stop spin from another thread. The obvious
solution would be to throw it an exception. However, that leaks a socket
(t) if the exception arrives between (*) and (**). I could wrap the whole
thing in block, but from looking at the source of Network.Socket it seems
that accept itself is not exception safe; so no matter what I do, I can't
use asynchronous exceptions to make spin exit.

(Is this actually true? Should accept be fixed (along with a lot of other
library functions)?)

Another idea is to sClose s in another thread. This makes accept throw an
IO exception, which breaks the loop. Yay! But it introduces another race
condition: If a third thread creates a socket between sClose and accept,
the underlying file descriptor of s may get reused, leading to silently
wrong behavior because accept listens on the wrong socket now.

My question is: How can I use accept in a loop so that I can safely stop
it from another thread?


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


Re: [Haskell-cafe] Binary serialization, was Re: Abstraction leak

2007-07-05 Thread Donald Bruce Stewart
p.f.moore:
 On 05/07/07, Jonathan Cast [EMAIL PROTECTED] wrote:
 Can't say I agree.  I've been learning Python, and have been very 
 un-impressed
 so far with its library coverage, which I would rate no better than (in 
 terms
 of the POSIX bindings, worse than) Haskell.
 
 It probably depends on your perspective. I've found lots of tasks that
 would be a simple library call in Python, but which require me to
 write the code myself in Haskell. Examples:
 
 * Send an email

Sounds like a job for MissingH?

 * Parse an ini file

Probably have to write your own Parsec-based parser here.

 * Gzip compress a data stream

We have a wonderful library for this!

http://hackage.haskell.org/cgi-bin/hackage-scripts/package/zlib-0.3

 * Calculate the MD5 checksum of a file

In the Crypto library, or use the openssl binding posted a couple of
days ago:

   http://thread.gmane.org/gmane.comp.lang.haskell.cafe/24165/focus=24170 

 
 (Of course, I may just not have found the relevant library - that says
 something about discoverability rather than coverage, I guess).


Find more libraries on hackage:

http://hackage.haskell.org/packages/archive/pkg-list.html

 For bindings, Python's Windows bindings (pywin32) are superb, where
 Haskell's are minimal and unmaintained. Of course, that won't matter
 to you if you use POSIX...
 
 The one thing off the top of my head that Python had was Base64, but 
 that's 20
 lines of Haskell tops.  Aside from that, nothing.
 
 But that's 20 lines of code I don't want to write, and more, I don't
 know how to write (without looking up the definition of Base64).
 Having lots of these seemingly trivial helpers available out of the
 box is what library coverage means to me. (And Python does have lots
 of these - I don't know how Haskell fares in practice).
 
 I'm not trying to start (or fan) a flamewar, but it's interesting how
 different people's perspectives on libraries can be...

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


[Haskell-cafe] reimplementing break (incorrectly) quickcheck p list gives me feedback that it breaks on list, but not what predicate test caused the breakage

2007-07-05 Thread Thomas Hartman
I am a total quickcheck noob. Is there a way to find out what predicate 
test function is, below?

Also, is there a way I can ask quickcheck to test lists of various built 
in types, not just Int?

***

Falsifiable, after 4 tests:
function
[1]
*Recursion testMyBreak
Falsifiable, after 1 tests:
function
[-1,1,2]
*Recursion


testMyBreak= quickCheck $ \p l - myBreak p (l :: [Int]) == break p l
myBreak t xs =
let f t next rest =
  if t next 
then ([], snd rest)
else (next : fst rest, snd rest)
  in foldr ( f t ) ([],[]) xs

---

This e-mail may contain confidential and/or privileged information. If you 
are not the intended recipient (or have received this e-mail in error) 
please notify the sender immediately and destroy this e-mail. Any 
unauthorized copying, disclosure or distribution of the material in this 
e-mail is strictly forbidden.___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] interrupting an accept()ing thread

2007-07-05 Thread Donald Bruce Stewart
drtomc:
 On 7/6/07, Lukas Mai [EMAIL PROTECTED] wrote:
 Hello, cafe!
 
 Have you been reading my mind? See the other recent Cafe thread (um,
 titled something about System.Exit).
 
 Here's my solution:

...

If you've got small examples illustrating how to use the various
concurrency abstractions, feel free to add them to:

http://haskell.org/haskellwiki/Concurrency_demos

So we can build up a large body of examples for all the libs and tricks
out there.

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


[Haskell-cafe] Re: folds with escapes

2007-07-05 Thread Logan Capaldo
Michael Vanier mvanier at cs.caltech.edu writes:

 
 I'm sure this has been done a hundred times before, but a simple
generalization of foldl just 
 occurred to me and I wonder if there's anything like it in the standard
libraries (I couldn't find 
 anything).  Basically, I was trying to define the any function in terms of a
fold, and my first 
 try was this:
 
   any :: (a - Bool) - [a] - Bool
   any p = foldl (\b x - b || p x) False
 
 This is inefficient, because if (p x) is ever True the rest of the list is
scanned unnecessarily. 
 So I wrote a more general foldl with an escape predicate which terminates
the evaluation, along 
 with a function which tells what to return in that case (given an argument of
the running total 'z'):
 
   foldle :: (b - Bool) - (a - a) - (a - b - a) - a - [b] - a
   foldle _ _ _ z [] = z
   foldle p h f z (x:xs) = if p x then h z else foldle p h f (f z x) xs
 
 Using this function, foldl is:
 
   foldl' = foldle (const False) id
 
 and any is just:
 
   any p = foldle p (const True) const False
 

There have already been better responses / solutions to this, 
but I just wanted to point out that there was already a 
form of an escaping left fold, namely foldM.

 import Data.Maybe ( isJust )
 import Control.Monad ( foldM )

 any p = not . isJust . foldM (\_ x - if p x then Nothing 
  else Just ()) ()

Of course the logic is a little confusing to read :)


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


Re: [Haskell-cafe] interrupting an accept()ing thread

2007-07-05 Thread Thomas Conway

On 7/6/07, Lukas Mai [EMAIL PROTECTED] wrote:

Hello, cafe!


Have you been reading my mind? See the other recent Cafe thread (um,
titled something about System.Exit).

Here's my solution:

acceptLoop sok reqChan = do
   req - Network.Socket.accept sok
   atomically (writeTChan reqChan req)
   acceptLoop sok reqChan

mainLoop reqChan quitVar liveOpCountVar = do
   action - atomically (quitNow `orElse` getReq)
   case action of
   Nothing - return ()
   Just (reqSok,reqAddr) - do
   atomically $ do
   liveOpCount - readTVar liveOpCountVar
   writeTVar liveOpCountVar (liveOpCount + 1)
   forkIO (doSession reqSok reqAddr quitVar liveOpCountVar)
   mainLoop reqChan quitVar liveOpCountVar
   where
   quitNow = do
   q - readTVar quitVar
   case q of
   True - return Nothing
   False - retry

   getReq = do
   req - readTChan reqChan
   return (Just req)

doit sok = do
   reqChan - atomically newTChan
   quitVar - atomically (newTVar False)
   liveOpCountVar - atomically (newTVar 0)
   forkIO (acceptLoop sok reqChan)
   mainLoop reqChan quitVar liveOpCountVar
   atomically $ do
   liveOpCount - readTVar liveOpCountVar
   if liveOpCount  0
   then retry
   else return ()

Although doSession is not included, obviously when you want to quit,
something in doSession should set quitVar to True. Also, as suggested
elsewhere, doSession should involve a finally clauses to make sure
the live op count gets decremented.

T.
--
Dr Thomas Conway
[EMAIL PROTECTED]

Silence is the perfectest herald of joy:
I were but little happy, if I could say how much.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] A very nontrivial parser

2007-07-05 Thread Donald Bruce Stewart
andrewcoppin:
 Jonathan Cast wrote:
 On Thursday 05 July 2007, Andrew Coppin wrote:
   
 ...OK, anybody have a solution that works in Haskell 98?
 
 
 Rank-2 types are perhaps /the/ most common, widely accepted extension to 
 Haskell 98, after the approved addendum for FFI and the draft addendum for 
 hierarchical modules.  I would really be concerned about using them (it's 
 certainly not like they're going to just disappear on you one day, like 
 say functional dependencies almost certainly will).  But that's just me.
   
 
 Personally, I just try to avoid *all* language extensions - mainly 
 because most of them are utterly incomprehensible. (But then, perhaps 
 that's just because they all cover extremely rare edge cases?)

Some cover edge cases, some are just useful.  What about:

* the FFI
* bang patterns
* pattern guards
* newtype deriving

Surely, fairly simple, useful. Used a lot? :-)
 
-- Don
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] A very nontrivial parser

2007-07-05 Thread Stefan O'Rear
On Fri, Jul 06, 2007 at 10:56:43AM +1000, Donald Bruce Stewart wrote:
 andrewcoppin:
  Jonathan Cast wrote:
  On Thursday 05 July 2007, Andrew Coppin wrote:

  ...OK, anybody have a solution that works in Haskell 98?
  
  
  Rank-2 types are perhaps /the/ most common, widely accepted extension to 
  Haskell 98, after the approved addendum for FFI and the draft addendum for 
  hierarchical modules.  I would really be concerned about using them (it's 
  certainly not like they're going to just disappear on you one day, like 
  say functional dependencies almost certainly will).  But that's just me.

  
  Personally, I just try to avoid *all* language extensions - mainly 
  because most of them are utterly incomprehensible. (But then, perhaps 
  that's just because they all cover extremely rare edge cases?)
 
 Some cover edge cases, some are just useful.  What about:
 
 * the FFI
 * bang patterns
 * pattern guards
 * newtype deriving
 
 Surely, fairly simple, useful. Used a lot? :-)

How about . in module names?

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


Re: [Haskell-cafe] interrupting an accept()ing thread

2007-07-05 Thread Lukas Mai
Am Freitag, 6. Juli 2007 02:13 schrieb Thomas Conway:

 Here's my solution:

 acceptLoop sok reqChan = do
 req - Network.Socket.accept sok
 atomically (writeTChan reqChan req)
 acceptLoop sok reqChan

 mainLoop reqChan quitVar liveOpCountVar = do
 action - atomically (quitNow `orElse` getReq)
 case action of
 Nothing - return ()
 Just (reqSok,reqAddr) - do
 atomically $ do
 liveOpCount - readTVar liveOpCountVar
 writeTVar liveOpCountVar (liveOpCount + 1)
 forkIO (doSession reqSok reqAddr quitVar liveOpCountVar)
 mainLoop reqChan quitVar liveOpCountVar
 where
 quitNow = do
 q - readTVar quitVar
 case q of
 True - return Nothing
 False - retry

 getReq = do
 req - readTChan reqChan
 return (Just req)

 doit sok = do
 reqChan - atomically newTChan
 quitVar - atomically (newTVar False)
 liveOpCountVar - atomically (newTVar 0)
 forkIO (acceptLoop sok reqChan)
 mainLoop reqChan quitVar liveOpCountVar
 atomically $ do
 liveOpCount - readTVar liveOpCountVar
 if liveOpCount  0
 then retry
 else return ()

 Although doSession is not included, obviously when you want to quit,
 something in doSession should set quitVar to True. Also, as suggested
 elsewhere, doSession should involve a finally clauses to make sure
 the live op count gets decremented.

I don't see how this solves the problem. AFAICS acceptLoop never returns
and sok is never closed. On the other hand, my program doesn't need a
liveOpCount because the subthreads take care of themselves. It's just the
accept loop I need to break somehow.

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


Re: [Haskell-cafe] interrupting an accept()ing thread

2007-07-05 Thread Thomas Conway

On 7/6/07, Lukas Mai [EMAIL PROTECTED] wrote:

I don't see how this solves the problem. AFAICS acceptLoop never returns
and sok is never closed. On the other hand, my program doesn't need a
liveOpCount because the subthreads take care of themselves. It's just the
accept loop I need to break somehow.


Well, it works because the sub-thread dies when the program exits, so
the socket gets closed then.

T.
--
Dr Thomas Conway
[EMAIL PROTECTED]

Silence is the perfectest herald of joy:
I were but little happy, if I could say how much.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe