Re: [Haskell-cafe] Intersection types for Haskell?

2006-01-10 Thread David Menendez
Brian Hulley writes:

> Also, as a second point, could functional dependencies in type
> classes be written using a similar syntax eg instead of
> 
> class Insert t c a | c a -> t where
> insert :: t -> c a -> c a
> 
> we could write:
> 
> class Insert (h (c a)) c a where
> insert :: h (c a) -> c a -> c a
> 
> or
> class Insert t@(h (c a)) c a where   -- re-using as-pattern syntax
> insert :: t -> c a -> c a
> 
> to avoid having to have a special syntax just for functional
> dependencies and/or to be able to write more complicated fundeps more
> succinctly?

You might be interested in associated types and associated type
synonyms[1]. These are alternatives to functional dependencies which are
less powerful but possibly easier to use. (Of course, no Haskell
compiler supports them.)

For example:

class Collection c where
type Elem c

insert :: Elem c -> c -> c
...

instance Collection [a] where
type Elem [a] = a

insert = (:)
...

Your example, in the syntax of associated type synonyms, would look
something like this:

class Insert c a where
type T c a
insert :: T c a -> c a -> c a


[1]: 
-- 
David Menendez <[EMAIL PROTECTED]> | "In this house, we obey the laws
  |of thermodynamics!"
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Intersection types for Haskell?

2006-01-10 Thread Brian Hulley

Brian Hulley wrote:


which is perhaps clearer and prevents bad types such as (Int ->
String & Int -> Char) by construction.


Oops! I forgot that functions with such types can exist via multi-parameter 
type classes and overloading - this may be one reason why intersection types 
have not yet been added to Haskell.


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


Re: [Haskell-cafe] rank-2 :(

2006-01-10 Thread Ross Paterson
On Tue, Jan 10, 2006 at 08:47:32PM +0300, Bulat Ziganshin wrote:
> those rank-2 types wil make me mad :)
> 
> encodeHelper :: (MRef m r, Binary m a, BitStream m (StringBuffer m r))
>  => a -> m String
> encodeHelper x = do h <- newStringBuffer "" stringBufferDefaultCloseFunc
> put_ h x
> getStringBuffer h
> encode x = runST (encodeHelper x)
> 
> i can't force `encode` to compile, either with or without any type
> signatures. actually, signature for `encodeHelper` was developed by
> Hugs, but now i don't know how to proceed further
> 
> just now tried to force Hugs tell me its type. mission impossible :)
> 
> DataAltBinaryClass> :t (runST (encodeHelper 1))
> ERROR - Cannot justify constraints in application
> *** Expression: encodeHelper 1
> *** Type  : ST c [Char]
> *** Given context : ()
> *** Constraints   : (Num b, Binary (ST c) b)

It's telling you that your expression is ill-typed, and that

encodeHelper 1 :: (Num b, Binary (ST s) b) => ST s String

runST is declared with an argument type in which s is unconstrained,
so this is rejected.

> Binary class in my library includes monad in its header. May be it's
> the cause of problems?
> 
> class Binary m a where
> -- | Convert value to sequence of bits and write it to the stream
> put_   :: (BitStream m h) => h -> a -> m ()

Yes, that's the problem.

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


Re: [Haskell-cafe] Fannkuch timings

2006-01-10 Thread Donald Bruce Stewart
daniel.is.fischer:
> Am Dienstag, 10. Januar 2006 19:11 schrieben Sie:
> > Hello Daniel,
> >
> > Tuesday, January 10, 2006, 7:40:24 PM, you wrote:
> >
> > DF> These are user/MUT times, at the moment, my machine is busy, so that
> > elapsed DF> time is about double that, otherwise these times are rather
> > consistently DF> reproduced (between 8.4 and 8.9 for pure, 1.7 and 1.9 for
> > impure, clean DF> imperative I've done only twice, second run took 4.82s
> > MUT time).
> >
> > on the busy machine even MUT times may be (and even should be)
> > inaccurate because other threads will throw out data in CPU caches
> 
> So that explains (not surprisingly) that MUT times on the busy machine are 
> slightly higher (8.9 resp. 1.9), while on an otherwise idle machine, I 
> consistently got values in the range of 8.4 - 8.7 (I'm not absolutely sure, 
> but I think actually the range was 8.55 - 8.7) resp. 1.7 - 1.78 secs.
> 
> The problem remains, why is the speed-ratio so different for the different 
> algorithms?

Some things I can think of:
* OpenBSD vs Linux. I've noticed on some benchmarks large (2x) 
  differences between the same code running on the two OSs. Code
  that runs 2x faster on openbsd, compared to and older version of
  the code, will show no speedup on linux.
* Cpu arch. I'm testing on a Penitium M. This 1.6Ghz Pentium M
  outperforms a 2.4Ghz P4 sitting on my desk.
* Cache size.
Etc.

-- Don

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


Re: [Haskell-cafe] Fannkuch timings

2006-01-10 Thread Daniel Fischer
Am Dienstag, 10. Januar 2006 19:11 schrieben Sie:
> Hello Daniel,
>
> Tuesday, January 10, 2006, 7:40:24 PM, you wrote:
>
> DF> These are user/MUT times, at the moment, my machine is busy, so that
> elapsed DF> time is about double that, otherwise these times are rather
> consistently DF> reproduced (between 8.4 and 8.9 for pure, 1.7 and 1.9 for
> impure, clean DF> imperative I've done only twice, second run took 4.82s
> MUT time).
>
> on the busy machine even MUT times may be (and even should be)
> inaccurate because other threads will throw out data in CPU caches

So that explains (not surprisingly) that MUT times on the busy machine are 
slightly higher (8.9 resp. 1.9), while on an otherwise idle machine, I 
consistently got values in the range of 8.4 - 8.7 (I'm not absolutely sure, 
but I think actually the range was 8.55 - 8.7) resp. 1.7 - 1.78 secs.

The problem remains, why is the speed-ratio so different for the different 
algorithms?

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


Re: [Haskell-cafe] Space usage problems

2006-01-10 Thread Ian Lynagh
On Tue, Jan 10, 2006 at 04:44:33PM +, Ian Lynagh wrote:
> 
> readChunks :: FirstMonad String
> readChunks = do xs <- get
> if null xs then return []
>else do let (ys, zs) = foo xs
>put zs
>rest <- readChunks
>return (ys ++ rest)

It looks like changing this let to a case fixes this example, but at the
time I'd experimented with that there must have been other issues
clouding the effect, such as the following.

Foo1 (attached) uses large amounts of memory whereas Foo2 (also
attached) runs in a little constant space. The difference is only
changing this:

else do chunk <- case foo xs of
 (ys, zs) ->
 do put zs
return ys
chunks <- readChunks
return (chunk ++ chunks)

to this:

else case foo xs of
 (ys, zs) ->
 do put zs
chunks <- readChunks
return (ys ++ chunks)

but I don't have a good feeling for why this should be the case given
I'd expect chunk to be forced, and thus the case evaluated, at the same
point in Foo1 as the case is evaluated in Foo2.

Is this just a case of GHC's optimiser's behaviour depending on subtle
source changes, or am I missing something?


Thanks
Ian


module Main (main) where

import Control.Monad (liftM)
import Control.Monad.State (State, runState, evalState, get, put)

main :: IO ()
main = do xs <- readFile "data"
  ys <- readFile "data"
  print (evalState readChunks xs == ys)

---

type FirstMonad = State String

readChunks :: FirstMonad String
readChunks = do xs <- get
if null xs then return []
   else do chunk <- case foo xs of
(ys, zs) ->
do put zs
   return ys
   chunks <- readChunks
   return (chunk ++ chunks)

---

type SecondMonad = State String

foo :: String -> (String, String)
foo = runState bar

bar :: SecondMonad String
bar = do inp <- get
 case inp of
 [] -> return []
 x:xs -> do put xs
liftM (x:) bar


module Main (main) where

import Control.Monad (liftM)
import Control.Monad.State (State, runState, evalState, get, put)

main :: IO ()
main = do xs <- readFile "data"
  ys <- readFile "data"
  print (evalState readChunks xs == ys)

---

type FirstMonad = State String

readChunks :: FirstMonad String
readChunks = do xs <- get
if null xs then return []
   else case foo xs of
(ys, zs) ->
do put zs
   chunks <- readChunks
   return (ys ++ chunks)

---

type SecondMonad = State String

foo :: String -> (String, String)
foo = runState bar

bar :: SecondMonad String
bar = do inp <- get
 case inp of
 [] -> return []
 x:xs -> do put xs
liftM (x:) bar

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


Re: [Haskell-cafe] Space usage problems

2006-01-10 Thread Daniel Fischer
Am Dienstag, 10. Januar 2006 17:44 schrieb Ian Lynagh:
> Hi all,
>
> I am having space issues with some decompression code; I've attached a
> much simplified version as Test1.hs.
>
> At the bottom (foo/bar) is the equivalent of deflate. This should be a
> standalone module which doesn't know about the rest.
>
> In the middle (readChunks) is the equivalent of gunzip. It repeatedly
> calls foo until there is no more input left.
>
> At the top is a simple main function that calls them.
>
> If I do
>
> dd if=/dev/zero of=data bs=1000 count=3000" # making data around 3MB
> ghc --make Test1 -o Test1 -O -Wall
> ./Test1
>
> then in top I see Test1 increasing memory usage to around 150MB. I think
> this is because the "let (ys, zs) = foo xs" means zs holds on to xs
> (it's hard to be sure as compiling for profiling is too happy to change
> the behaviour).

I had 72 Mb space usage for a 3Mb file.

I believe, it's the 'put zs' that's consuming the memory. I changed it to

readChunks = do xs <- get
if null xs then return []
   else do let (ys, zs) = foo xs
   rest = evalState readChunks zs
   return (ys ++ rest)

and got much smaller memory usage (10Mb) -- not sure, how sensible that would 
be for real work and why it reduces memory. If bar can start returning before 
it's finished, then the same holds for the modified readChunks, but the 
original would have to wait for the completion of bar (via foo) until zs can 
be put, so the complete ys would have to be in memory at once.

Just checked, modified version also runs in 10Mb for a 12mb data file, 
so indeed bar starts returning before finishing and it seems the above is 
right.
./test4 +RTS -sstderr
True
1,496,184,404 bytes allocated in the heap
987,852,924 bytes copied during GC
  3,226,492 bytes maximum residency (162 sample(s))

   5707 collections in generation 0 ( 12.66s)
162 collections in generation 1 ( 14.82s)

 10 Mb total memory in use

  INIT  time0.00s  (  0.01s elapsed)
  MUT   time6.88s  ( 15.06s elapsed)
  GCtime   27.48s  ( 55.93s elapsed)
  EXIT  time0.00s  (  0.00s elapsed)
  Total time   34.36s  ( 71.00s elapsed)

  %GC time  80.0%  (78.8% elapsed)

  Alloc rate217,468,663 bytes per MUT second

  Productivity  20.0% of total user, 9.7% of total elapsed


>
> I tried (Test2) changing foo to be a monad transformer over the calling
> monad, so the caller's remaining input was updated as we went along, but
> (as well as memory usage not obviously being fixed) this is giving me a
> stack overflow.
>
>
> Has anyone got any suggestions for making a constant space, constant
> stack version?
>
>
> Thanks
> Ian

Hope that helps,
Daniel

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


Re[2]: [Haskell-cafe] Fannkuch timings

2006-01-10 Thread Bulat Ziganshin
Hello Daniel,

Tuesday, January 10, 2006, 7:40:24 PM, you wrote:

DF> These are user/MUT times, at the moment, my machine is busy, so that elapsed
DF> time is about double that, otherwise these times are rather consistently 
DF> reproduced (between 8.4 and 8.9 for pure, 1.7 and 1.9 for impure, clean 
DF> imperative I've done only twice, second run took 4.82s MUT time).

on the busy machine even MUT times may be (and even should be)
inaccurate because other threads will throw out data in CPU caches

-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]



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


Re: [Haskell-cafe] Re: hPutStrLn and hFlush

2006-01-10 Thread John Meacham
On Tue, Jan 10, 2006 at 09:40:41AM +, Simon Marlow wrote:
> John Meacham wrote:
> >Yeah. this is a major bug in ghc IMHO. I believe it has been fixed, but
> >am unsure.
> 
> It hasn't been fixed, this is the current behaviour and it's likely to 
> stay that way, I'm afraid.
> 
> We used to run finalizers on exit, but we stopped doing that for various 
> reasons.  Even when we did run finalizers on exit, we couldn't guarantee 
> to run all of them.

oh, the bug I was refering to was not not running finalizers on exit
(which makes sense) but rather not flushing file handles on exit. the
implication being that flushing the file handles should be done via some
other mechanism than the GC finalizer.

> >Since we can't rely on finalizers to run in general, some
> >sort of 'atexit' routine is needed. (which would be a good addition to
> >the standard libraries anyway)
> 
> You can implement atexit quite straightforwardly, if that's what you want.
> 
> exits = unsafePerformIO (newIORef []) :: IORef [IO ()]
> main = do_stuff `finally` (readIORef exits >>= sequence_ . reverse)
> atexit io = modifyIORef exits (io:)

The problem is that people would have to know to put that in main, so
the atexit functionality could not be used from libraries. I am thinking
something more akin to C's atexit(3) function provided by its standard
libraries.

a proposed interface would be

module System.Exit  -- append to the current System.Exit

data AtExitHandle

-- | add a routine to be called on program exit
addHandle :: IO () -> IO AtExitHandle
-- | remove a routine previously set to be run on program exit, this actios is 
idempotent.
removeHandle :: AtExitHandle -> IO ()
-- | run and remove a routine atomically, guarenteed to run routine at most 
once, even if called multiple times
runRemoveHandle :: AtExitHandle -> IO ()


so, hOpen will do an 
addHandle (hClose h) stowing the AtExitHandle and hClose will do a removeHandle 
on the AtExitHandle

I will happily implement this, I have needed it on several occasions
when working on real-world programs especially since the (correct)
decision to not ensure finalizers are run. (like making sure the terminal mode
is reset, or that certain resources (lock files, SYSV semaphores) are released)

in addition, I would add a _exitWith to System.Exit as the obvious
parallel to _exit(2).

John

-- 
John Meacham - ⑆repetae.net⑆john⑈ 
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Intersection types for Haskell?

2006-01-10 Thread Brian Hulley

Brian Hulley wrote:

Taral wrote:

I have no idea what kind of function would have type (a -> b & c ->
d). Can you give an example?


g x = x

because g 3 = 3 so g has type Int -> Int but also g 'a' = 'a' so g
has type Char -> Char hence g has type Int -> Int & Char -> Char


Actually I should have said "g's type *matches* (Int->Int & Char->Char)" 
since of course g has type a->a.


Regards, Brian. 


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


Re: [Haskell-cafe] Intersection types for Haskell?

2006-01-10 Thread Brian Hulley

Taral wrote:

On 1/10/06, Brian Hulley <[EMAIL PROTECTED]> wrote:

Hi -
I'm wondering if there is any possiblility of getting intersection
types into Haskell. For example, at the moment there is no (proper)
typing for:

f g x y = (g x, g y)

Ideally, I'd like to be able to write:

f:: (a -> b & c -> d) -> a -> c -> (b,d)


I have no idea what kind of function would have type (a -> b & c ->
d). Can you give an example?


g x = x

because g 3 = 3 so g has type Int -> Int but also g 'a' = 'a' so g has type 
Char -> Char hence g has type Int -> Int & Char -> Char


Also, h x = (x,x) ie Int -> (Int,Int) & Char -> (Char,Char)

The reason I can't just use a -> b for g's type is that then I would have no 
way to write out the result of f, since it is not (b,b)





f :: (a -> b a) -> c -> d -> (b c, b d)


f :: (forall a. a -> b a) -> c -> d -> (b c, b d)


That would be nice but unfortunately is not accepted by GHC because it 
cannot unify a->a with a -> b a, for example the following does not compile:


{-# OPTIONS -fglasgow-exts #-}

f :: (forall a. a -> b a) -> c -> d -> (b c, b d)
f g x y = (g x, g y)

g x = x

main = do
putStrLn (show (f g 3 'c'))

Regards,
Brian Hulley

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


Re: [Haskell-cafe] Intersection types for Haskell?

2006-01-10 Thread Taral
On 1/10/06, Brian Hulley <[EMAIL PROTECTED]> wrote:
> Hi -
> I'm wondering if there is any possiblility of getting intersection types
> into Haskell. For example, at the moment there is no (proper) typing for:
>
> f g x y = (g x, g y)
>
> Ideally, I'd like to be able to write:
>
> f:: (a -> b & c -> d) -> a -> c -> (b,d)

I have no idea what kind of function would have type (a -> b & c ->
d). Can you give an example?

> f :: (a -> b a) -> c -> d -> (b c, b d)

f :: (forall a. a -> b a) -> c -> d -> (b c, b d)

--
Taral <[EMAIL PROTECTED]>
"Computer science is no more about computers than astronomy is about
telescopes."
-- Edsger Dijkstra
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] In for a penny, in for a pound.

2006-01-10 Thread Isaac Gouy
--- Chris Kuklewicz <[EMAIL PROTECTED]>
wrote:
> I have two strong suggestions:
> * whoever does submit them should "diff" the output
> with a previously accepted version.
-snip-

Simply diff program output with the example output
file (there's now an output file link in each problem
description). 

Of course, that won't guarantee the program is correct
but it'll catch simple formating problems. There's a
simple formating problem with the regex-dna program

http://shootout.alioth.debian.org/gp4/benchmark.php?test=regexdna&lang=ghc&id=2#log




__
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Intersection types for Haskell?

2006-01-10 Thread Brian Hulley

José Miguel Vilaça wrote:

Hi

If I understand your problem than the following is a solution:

--

{-# OPTIONS -fglasgow-exts #-}

class Foo a b where
   g :: a -> b

type A = {- change the following -} Int
type B = {- change the following -} Char

instance Foo A B where
   g a = {- change the following -} ' '

type C = {- change the following -} Float
type D = {- change the following -} String

instance Foo C D where
   g c = {- change the following -} ""


f :: (Foo a b, Foo c d) => a -> c -> (b, d)
f x y = (g x, g y)


Thanks for the workaround. However this does not seem to be quite so general 
as intersection types, because it would only allow me to define f for some 
specific g ie the g of Foo, rather than for any general function...


Regards,
Brian Hulley 


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


RE: [Haskell-cafe] Intersection types for Haskell?

2006-01-10 Thread José Miguel Vilaça
Hi

If I understand your problem than the following is a solution:

--

{-# OPTIONS -fglasgow-exts #-}

class Foo a b where 
   g :: a -> b

type A = {- change the following -} Int
type B = {- change the following -} Char
   
instance Foo A B where
   g a = {- change the following -} ' '
   
type C = {- change the following -} Float
type D = {- change the following -} String

instance Foo C D where
   g c = {- change the following -} ""
  
 
f :: (Foo a b, Foo c d) => a -> c -> (b, d)  
f x y = (g x, g y)

-

Simply create a class an give instances for the wanted types.

The code above is also in a file in attachment.


cheers

José Miguel Vilaça 
Departamento de Informática - Universidade do Minho 
[EMAIL PROTECTED]

 
-Mensagem original-
De: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] Em nome de Brian Hulley
Enviada: terça-feira, 10 de Janeiro de 2006 18:01
Para: Haskell-cafe
Assunto: [Haskell-cafe] Intersection types for Haskell?

Hi -
I'm wondering if there is any possiblility of getting intersection types 
into Haskell. For example, at the moment there is no (proper) typing for:

f g x y = (g x, g y)

Ideally, I'd like to be able to write:

f:: (a -> b & c -> d) -> a -> c -> (b,d)

or

f :: (a -> b a) -> c -> d -> (b c, b d)

which is perhaps clearer and prevents bad types such as (Int -> String & 
Int -> Char) by construction.

While it may be impossible (?) to infer such a type for f, would it be 
possible to make use of such an annotation (esp since Haskell with GHC 
extensions already has arbitary rank polymorphism)?

Also, as a second point, could functional dependencies in type classes be 
written using a similar syntax eg instead of

class Insert t c a | c a -> t where
insert :: t -> c a -> c a

we could write:

class Insert (h (c a)) c a where
insert :: h (c a) -> c a -> c a

or
class Insert t@(h (c a)) c a where   -- re-using as-pattern syntax
insert :: t -> c a -> c a

to avoid having to have a special syntax just for functional dependencies 
and/or to be able to write more complicated fundeps more succinctly?

Regards,
Brian Hulley 

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


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


[Haskell-cafe] Intersection types for Haskell?

2006-01-10 Thread Brian Hulley

Hi -
I'm wondering if there is any possiblility of getting intersection types 
into Haskell. For example, at the moment there is no (proper) typing for:


   f g x y = (g x, g y)

Ideally, I'd like to be able to write:

   f:: (a -> b & c -> d) -> a -> c -> (b,d)

or

   f :: (a -> b a) -> c -> d -> (b c, b d)

which is perhaps clearer and prevents bad types such as (Int -> String & 
Int -> Char) by construction.


While it may be impossible (?) to infer such a type for f, would it be 
possible to make use of such an annotation (esp since Haskell with GHC 
extensions already has arbitary rank polymorphism)?


Also, as a second point, could functional dependencies in type classes be 
written using a similar syntax eg instead of


   class Insert t c a | c a -> t where
   insert :: t -> c a -> c a

we could write:

   class Insert (h (c a)) c a where
   insert :: h (c a) -> c a -> c a

or
   class Insert t@(h (c a)) c a where   -- re-using as-pattern syntax
   insert :: t -> c a -> c a

to avoid having to have a special syntax just for functional dependencies 
and/or to be able to write more complicated fundeps more succinctly?


Regards,
Brian Hulley 


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


Re: [Haskell-cafe] Space usage problems

2006-01-10 Thread Chris Kuklewicz
I will continue to guess...

Ian Lynagh wrote:
> On Tue, Jan 10, 2006 at 05:28:03PM +, Chris Kuklewicz wrote:
> 
>>I'll make a guess...
>>
>>Ian Lynagh wrote:
>>
>>>Hi all,
>>>
>>>foo :: String -> (String, String)
>>>foo = runState bar
>>>
>>>bar :: SecondMonad String
>>>bar = do inp <- get
>>> case inp of
>>> [] -> return []
>>> x:xs -> do put xs
>>>liftM (x:) bar
>>
>>The liftM should be equivalent to
>>  temp <- bar
>>  return ( (x:) temp )
>>
>>It looks like the first call to foo will have bar consuming the entire
>>input string.
> 
> 
> I'm not entirely sure what you mean here. The result will be the entire
> input string, but State is a lazy monad, so it won't have to consume it
> all before it starts returning it.
> 
> For example, if you replace the definition of foo with
> 
> foo xs = (evalState bar xs, "")
> 
> then the program runs in constant space (but this isn't a solution to
> the real problem, as bar will only consume a prefix of the string
> there).
> 
Yes, exactly as I would have predicted.

Your "let (yx,zs) = foo xs
  put zs"
takes the second of the tuple retuned from "foo = runState bar" and
put's it.  Then in the recursive readChucks call, it does
  xs <- get
  if (null xs)

So it has to decide if xs (which is zs which is the snd value from foo
which is the state from runState bar which is "" or []) is null or not.

This forces it to get the head of the String state that bar returns, or
[] since there is no head.  But it does not know that it is [] until bar
is fully finished, which loads the whole file into memory.

When you put (evalState bar xs, "") then zs is [] and put [] leads to
get [] and null [] is true so it returns [] to the nested readChunks
call.  This does not force the file to be read.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] rank-2 :(

2006-01-10 Thread Bulat Ziganshin
Hello ,

those rank-2 types wil make me mad :)

encodeHelper :: (MRef m r, Binary m a, BitStream m (StringBuffer m r))
 => a -> m String
encodeHelper x = do h <- newStringBuffer "" stringBufferDefaultCloseFunc
put_ h x
getStringBuffer h
encode x = runST (encodeHelper x)

i can't force `encode` to compile, either with or without any type
signatures. actually, signature for `encodeHelper` was developed by
Hugs, but now i don't know how to proceed further

just now tried to force Hugs tell me its type. mission impossible :)

DataAltBinaryClass> :t (runST (encodeHelper 1))
ERROR - Cannot justify constraints in application
*** Expression: encodeHelper 1
*** Type  : ST c [Char]
*** Given context : ()
*** Constraints   : (Num b, Binary (ST c) b)


Binary class in my library includes monad in its header. May be it's
the cause of problems?

class Binary m a where
-- | Convert value to sequence of bits and write it to the stream
put_   :: (BitStream m h) => h -> a -> m ()

but it's needed because MArray types, for example, can be serialized
only in the appropriate monad:

instance Binary IO (IOArray a) where ...

-- 
Best regards,
 Bulat  mailto:[EMAIL PROTECTED]



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


Re: [Haskell-cafe] Space usage problems

2006-01-10 Thread Ian Lynagh
On Tue, Jan 10, 2006 at 05:28:03PM +, Chris Kuklewicz wrote:
> I'll make a guess...
> 
> Ian Lynagh wrote:
> > Hi all,
> > 
> > foo :: String -> (String, String)
> > foo = runState bar
> > 
> > bar :: SecondMonad String
> > bar = do inp <- get
> >  case inp of
> >  [] -> return []
> >  x:xs -> do put xs
> > liftM (x:) bar
> The liftM should be equivalent to
>   temp <- bar
>   return ( (x:) temp )
> 
> It looks like the first call to foo will have bar consuming the entire
> input string.

I'm not entirely sure what you mean here. The result will be the entire
input string, but State is a lazy monad, so it won't have to consume it
all before it starts returning it.

For example, if you replace the definition of foo with

foo xs = (evalState bar xs, "")

then the program runs in constant space (but this isn't a solution to
the real problem, as bar will only consume a prefix of the string
there).


Thanks
Ian

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


Re: [Haskell-cafe] Space usage problems

2006-01-10 Thread Chris Kuklewicz
I'll make a guess...

Ian Lynagh wrote:
> Hi all,
> 
> In the middle (readChunks) is the equivalent of gunzip. It repeatedly
> calls foo until there is no more input left.
> 
> At the top is a simple main function that calls them.
> 
> If I do
> 
> dd if=/dev/zero of=data bs=1000 count=3000" # making data around 3MB
> ghc --make Test1 -o Test1 -O -Wall
> ./Test1
> 
> then in top I see Test1 increasing memory usage to around 150MB. I think
> this is because the "let (ys, zs) = foo xs" means zs holds on to xs
> (it's hard to be sure as compiling for profiling is too happy to change
> the behaviour).

I don't have a comment on your guess.

> 
> I tried (Test2) changing foo to be a monad transformer over the calling
> monad, so the caller's remaining input was updated as we went along, but
> (as well as memory usage not obviously being fixed) this is giving me a
> stack overflow.

I will ignore Test2

> Has anyone got any suggestions for making a constant space, constant
> stack version?

Not yet.

> 
> 
> Thanks
> Ian

> 
> 
> 
> module Main (main) where
> 
> import Control.Monad (liftM)
> import Control.Monad.State (State, runState, evalState, get, put)
> 
> main :: IO ()
> main = do xs <- readFile "data"
>   ys <- readFile "data"
>   print (evalState readChunks xs == ys)

The equality should be constant space.

> 
> ---
> 
> type FirstMonad = State String
> 
> readChunks :: FirstMonad String
> readChunks = do xs <- get
> if null xs then return []
>else do let (ys, zs) = foo xs
>put zs
And zs is the final state of "runState bar" which is suspect is []
And ys is the whole input (which is now all in memory)
>rest <- readChunks
>return (ys ++ rest)
> 
> ---
> 
> type SecondMonad = State String
> 
> foo :: String -> (String, String)
> foo = runState bar
> 
> bar :: SecondMonad String
> bar = do inp <- get
>  case inp of
>  [] -> return []
>  x:xs -> do put xs
> liftM (x:) bar
The liftM should be equivalent to
  temp <- bar
  return ( (x:) temp )

It looks like the first call to foo will have bar consuming the entire
input string.

So the flow looks like

main

 readChuncks all-input

  foo all-input

   bar (iterated over whole input length)

   foo returns (all-input, [])

  "rest <- readChunks" (recursive call, sees null xs then "return []")

  "return (ys ++ rest)" which is return (all-input ++ [])


In essence, your bar traverses the whole string until the state is
empty.  This loads your whole file into memory
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Space usage problems

2006-01-10 Thread Ian Lynagh

Hi all,

I am having space issues with some decompression code; I've attached a
much simplified version as Test1.hs.

At the bottom (foo/bar) is the equivalent of deflate. This should be a
standalone module which doesn't know about the rest.

In the middle (readChunks) is the equivalent of gunzip. It repeatedly
calls foo until there is no more input left.

At the top is a simple main function that calls them.

If I do

dd if=/dev/zero of=data bs=1000 count=3000" # making data around 3MB
ghc --make Test1 -o Test1 -O -Wall
./Test1

then in top I see Test1 increasing memory usage to around 150MB. I think
this is because the "let (ys, zs) = foo xs" means zs holds on to xs
(it's hard to be sure as compiling for profiling is too happy to change
the behaviour).

I tried (Test2) changing foo to be a monad transformer over the calling
monad, so the caller's remaining input was updated as we went along, but
(as well as memory usage not obviously being fixed) this is giving me a
stack overflow.


Has anyone got any suggestions for making a constant space, constant
stack version?


Thanks
Ian


module Main (main) where

import Control.Monad (liftM)
import Control.Monad.State (State, runState, evalState, get, put)

main :: IO ()
main = do xs <- readFile "data"
  ys <- readFile "data"
  print (evalState readChunks xs == ys)

---

type FirstMonad = State String

readChunks :: FirstMonad String
readChunks = do xs <- get
if null xs then return []
   else do let (ys, zs) = foo xs
   put zs
   rest <- readChunks
   return (ys ++ rest)

---

type SecondMonad = State String

foo :: String -> (String, String)
foo = runState bar

bar :: SecondMonad String
bar = do inp <- get
 case inp of
 [] -> return []
 x:xs -> do put xs
liftM (x:) bar


module Main (main) where

import Control.Monad (liftM)
import Control.Monad.Trans (lift)
import Control.Monad.State (StateT, evalStateT, State, evalState, get, put)

main :: IO ()
main = do xs <- readFile "data"
  ys <- readFile "data"
  print (evalState readChunks xs == ys)

---

type InnerMonad = State String

readChunks :: InnerMonad String
readChunks = do xs <- get
if null xs then return []
   else do ys <- foo get put
   rest <- readChunks
   return (ys ++ rest)

---

data St m = St { get_inp :: m String, put_inp :: String -> m () }
type OuterMonad m = StateT (St m) m

foo :: Monad m => m String -> (String -> m ()) -> m String
foo getter putter = evalStateT bar (St getter putter)

bar :: Monad m => OuterMonad m String
bar = do st <- get
 inp <- lift $ get_inp st
 case inp of
 [] -> return []
 x:xs -> do lift $ put_inp st xs
liftM (x:) bar

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


Re: [Haskell-cafe] Fannkuch timings

2006-01-10 Thread Daniel Fischer
Am Dienstag, 10. Januar 2006 16:10 schrieben Sie:
> On 10/01/06, Daniel Fischer <[EMAIL PROTECTED]> wrote:
> > On my 1.2 GHz Duron (SuSE linux), I get significantly different timings
> > than those on the wiki. Sebastian Sylvan's, Kimberley Burchett's and
> > Bertram Felgenhauer's all take roughly thrice as long as posted (that's
> > rather consistent, but the factor is surprisingly large). Cale Gibbard's
> > takes 18.44 secs for N = 9, which is rather bad, I think.
>
> Well, yeah, it's known not to be as efficient as the others -- I threw
> it together rather quickly from some parts I had laying around. I
> unfortunately hadn't tried the naive implementation of permutations
> since it's actually faster. (My version ought to still be better than
> the original though.)
>
> > Really surprising (to me) are the following (N = 10)
> >
> > Algo   Wiki  Here
> > Clean imperative   2.1 s 4.54 s
> > Fastest Pure   1.8 s 8.65 s
> > Fastest Impure 1.4 s 1.77 s.
> >
> > So the ratio for the fast impure version is approximately 1.6GHz/1.2GHz,
> > which is natural, but the ratio for clean impure is 2.2 and for the fast
> > pure version, it's even 4.8!
> > All are compiled with -O2 -optc-O3.
> > Does that mean my system is really poor in producing binaries from pure
> > Haskell?
> > And why would that be so?
>
> Hmm... that's really odd. Which version of ghc/gcc are you using and
> how are you measuring the times? Perhaps other processes on your
> system are interfering? Do you get these numbers consistently?
>
>  - Cale

I use ghc 6.4.1 and gcc 3.3. Times are measured either by 
time ./fannPure 10 ...
or
./fannPure 10 +RTS -sstderr

These are user/MUT times, at the moment, my machine is busy, so that elapsed 
time is about double that, otherwise these times are rather consistently 
reproduced (between 8.4 and 8.9 for pure, 1.7 and 1.9 for impure, clean 
imperative I've done only twice, second run took 4.82s MUT time).

Any idea?

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


Re: [Haskell-cafe] RE: [Haskell] Haskell DB bindings (was Re: ANN: HDBC (HaskellDatabase Connectivity)

2006-01-10 Thread Björn Bringert

Bayley, Alistair wrote:

[Moving to café, too]



There are three active database libraries: HDBC, HSQL and Takusen.
It is quite disappointing from my point of view. Recently there was
the same situation with the GUI libraires. The Haskell Community is
quite small to waste efforts, developing different libraries for
the same things. When I started with HSQL there were only two
database libraries: HaSQL for ODBC and libpq for PostgreSQL. They
both are dead, I think. I decided that it is useful to have one
abstract API that can cover all database bindings. I imagine
something like JDBC, ADO or DBI for Haskell. If you guys would like
this to happen then lets discuss what we want. I would be happy to
work on single project that can satisfy all needs.

Cheers, Krasimir





... The Haskell Community is quite small to waste efforts,
developing different libraries for the same things.



Yes, that could be considered undesirable. However, there is the
choice for users over which API to choose that best supports their
needs. In the use of an enumerator, Takusen has chosen quite a
different design space from HSQL and HDBC. Whether or not that proves
to be a good idea, or attractive to users, remains to be seen :-)

HaskellDB+HSQL seems to be to be the most mature, and actively
maintained. Although I'm keen to progress Takusen, I find it hard at
present to take the necessary time, so work seems to stall. I'd have
no bone to pick with HaskellDB+HSQL being promoted as the default
database API, but I still want to work on Takusen, because I think
there are some ideas worth exploring.

When I started Takusen, I was specifically interested in using
HaskellDB to interface to Oracle. At the time, HaskellDB did not use
HSQL, and HSQL lacked a unifying interface, so I started work on a
low-level library to Oracle (I was also keen to learn to use the
FFI). The design later evolved towards the enumerator approach (Oleg
persuaded me that it was a good idea) and the HaskellDB goal was
never reached. Now that HSQL supports Oracle, I can choose to use
HaskellDB with Oracle, so I suppose my original goal has been
satisfied.


Just for the record, the current darcs version of HaskellDB [1] works 
with both HSQL and HDBC.


/Björn

[1] darcs get --partial http://cvs.haskell.org/darcs/haskelldb/

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


Re: [Haskell-cafe] Fannkuch timings

2006-01-10 Thread Cale Gibbard
On 10/01/06, Daniel Fischer <[EMAIL PROTECTED]> wrote:
> On my 1.2 GHz Duron (SuSE linux), I get significantly different timings than
> those on the wiki. Sebastian Sylvan's, Kimberley Burchett's and Bertram
> Felgenhauer's all take roughly thrice as long as posted (that's rather
> consistent, but the factor is surprisingly large). Cale Gibbard's takes 18.44
> secs for N = 9, which is rather bad, I think.

Well, yeah, it's known not to be as efficient as the others -- I threw
it together rather quickly from some parts I had laying around. I
unfortunately hadn't tried the naive implementation of permutations
since it's actually faster. (My version ought to still be better than
the original though.)

>
> Really surprising (to me) are the following (N = 10)
>
> Algo   Wiki  Here
> Clean imperative   2.1 s 4.54 s
> Fastest Pure   1.8 s 8.65 s
> Fastest Impure 1.4 s 1.77 s.
>
> So the ratio for the fast impure version is approximately 1.6GHz/1.2GHz, which
> is natural, but the ratio for clean impure is 2.2 and for the fast pure
> version, it's even 4.8!
> All are compiled with -O2 -optc-O3.
> Does that mean my system is really poor in producing binaries from pure
> Haskell?
> And why would that be so?

Hmm... that's really odd. Which version of ghc/gcc are you using and
how are you measuring the times? Perhaps other processes on your
system are interfering? Do you get these numbers consistently?

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


[Haskell-cafe] RE: [Haskell] Haskell DB bindings (was Re: ANN: HDBC (HaskellDatabase Connectivity)

2006-01-10 Thread Bayley, Alistair
[Moving to café, too] 

> There are three active database libraries: HDBC, HSQL and Takusen. It
> is quite disappointing from my point of view. Recently there was the
> same situation with the GUI libraires. The Haskell Community is quite
> small to waste efforts, developing different libraries for the same
> things. When I started with HSQL there were only two database
> libraries: HaSQL for ODBC and libpq for PostgreSQL. They both are
> dead, I think. I decided that it is useful to have one abstract API
> that can cover all database bindings. I imagine something like JDBC,
> ADO or DBI for Haskell. If you guys would like this to happen then
> lets discuss what we want. I would be happy to work on single project
> that can satisfy all needs.
> 
> Cheers,
>   Krasimir


> ... The Haskell Community is quite
> small to waste efforts, developing different libraries for the same
> things.

Yes, that could be considered undesirable. However, there is the choice for 
users over which API to choose that best supports their needs. In the use of an 
enumerator, Takusen has chosen quite a different design space from HSQL and 
HDBC. Whether or not that proves to be a good idea, or attractive to users, 
remains to be seen :-)

HaskellDB+HSQL seems to be to be the most mature, and actively maintained. 
Although I'm keen to progress Takusen, I find it hard at present to take the 
necessary time, so work seems to stall. I'd have no bone to pick with 
HaskellDB+HSQL being promoted as the default database API, but I still want to 
work on Takusen, because I think there are some ideas worth exploring.

When I started Takusen, I was specifically interested in using HaskellDB to 
interface to Oracle. At the time, HaskellDB did not use HSQL, and HSQL lacked a 
unifying interface, so I started work on a low-level library to Oracle (I was 
also keen to learn to use the FFI). The design later evolved towards the 
enumerator approach (Oleg persuaded me that it was a good idea) and the 
HaskellDB goal was never reached. Now that HSQL supports Oracle, I can choose 
to use HaskellDB with Oracle, so I suppose my original goal has been satisfied.

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


Re: [Haskell-cafe] Avoiding name collisions by using value spacesinstead of modules

2006-01-10 Thread Brian Hulley

Brian Hulley wrote:

Cale Gibbard wrote:

Unifying these two under a single operation is certainly trickier,
and it's a little more questionable that it should be done at all,
given that their types are so different -- below is the closest I
could come to it off-hand.



Thanks! I'm impressed. Obviously there is a lot more power in type
classes than I'd thought.


Of course, this still doesn't solve the original problem I was trying to 
address, namely that I want identifier bindings to be pulled into scope by 
their typed context (ie value type or return type + arg types) so that 
functional programmers could get the same advantages (in fact even more 
advantages) than OOP programmers.


With type classes, every use of any specific identifier, within the whole 
program, would have to be declared an instance of a single global type 
class, which would then be imported unqualified into the module so that you 
could write insert (1,2) m etc without having to qualify the word "insert". 
(Because if these type classes/instances were imported qualified we'd just 
swap "Set.insert" for "Collection.insert")


With the ty-tuple idea, all functions in a module are automatically 
organised into sub-modules and brought into scope only when needed, so every 
function in a program could be typed into a single file thus freeing the 
programmer from the onerous burden of having to work out where to put them 
manually. (The programmer would still put data declarations into different 
modules)


I must admit my thinking is strongly influenced by years of C++ programming, 
but so far I haven't seen any description of how one decides what module a 
function should be placed in in functional programming, and the existing 
module system seems like a pauper's alternative to static class methods in 
C++, C#, or Java, since in Haskell, you need to use the same name for the 
module and the type (for Data.Set etc) yet this choice of same name is not 
enforced by the language even though the user thinks of them as being "the 
same", and in fact two import directives are needed to maintain the illusion 
that they are the same so you can write Set a and Set.insert etc...


Regards,
Brian Hulley 


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


[Haskell-cafe] Fannkuch timings

2006-01-10 Thread Daniel Fischer
On my 1.2 GHz Duron (SuSE linux), I get significantly different timings than 
those on the wiki. Sebastian Sylvan's, Kimberley Burchett's and Bertram 
Felgenhauer's all take roughly thrice as long as posted (that's rather 
consistent, but the factor is surprisingly large). Cale Gibbard's takes 18.44 
secs for N = 9, which is rather bad, I think.

Really surprising (to me) are the following (N = 10)

Algo   Wiki  Here
Clean imperative   2.1 s 4.54 s
Fastest Pure   1.8 s 8.65 s
Fastest Impure 1.4 s 1.77 s.

So the ratio for the fast impure version is approximately 1.6GHz/1.2GHz, which 
is natural, but the ratio for clean impure is 2.2 and for the fast pure 
version, it's even 4.8!
All are compiled with -O2 -optc-O3.
Does that mean my system is really poor in producing binaries from pure 
Haskell?
And why would that be so?

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


RE: Re[2]: [Haskell-cafe] I/O and utf8

2006-01-10 Thread Bayley, Alistair
> From: [EMAIL PROTECTED] 
> [mailto:[EMAIL PROTECTED] On Behalf Of Bulat Ziganshin
> 
> i have the question about this issue - i also want to provide
> autodetection mechanism, which relies on first bytes of text files to
> set proper encoding. what is the standard rules to encode utf8/utf16
> encoding used for text in file in these first bytes?


Are you asking about the byte-order-mark in UTF encodings?
  http://www.unicode.org/faq/utf_bom.html#BOM

Note that UTF8 files typically lack the BOM, as UTF8 is meant to be
backwards-compatible with US7ASCII, I think. Windows Notepad is one of
the few programs that will insert it if a text file is saved as UTF8.

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


Re: [Haskell-cafe] hPutStrLn and hFlush

2006-01-10 Thread Sebastian Sylvan
On 1/9/06, Gracjan Polak <[EMAIL PROTECTED]> wrote:
>
> Hi all,
>
> A bit strange behaviour with hPutStrLn. Consider following program:
>
> main = do
> handle <- openFile "output.txt" WriteMode
> hPutStrLn handle (unlines contLines2)
> -- hFlush houtput
> where
> contLines2 = flip map [1..2000] $
>   \x -> show x ++ " been there done that"
>
> Outputs file which ends with following lines:
>
> 1989 been there done that
> 1990 been there done that
> 1991 been there done that
> 1992 been there done that
> 199
> (END)
>
> So the output is truncated. When I uncomment hFlush, file is fully written.
> Is this expected/documented behaviour?
>
> Platform: WinXP, GHC version 6.4.1
>

Looks like the buffering is BlockBuffering for your output. Try
changing that using hSetBuffering stdout LineBuffering (or
NoBuffering).

I believe it gets flushed if you close the file as well...

/S


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


Re[2]: [Haskell-cafe] I/O and utf8

2006-01-10 Thread Bulat Ziganshin
Hello John,

Tuesday, January 10, 2006, 2:08:44 AM, you wrote:

>> i want to read a file encoded in utf8 and at a later time output portions of 
>> it
>> on the console. Is there an easy way to do this in haskell? using the 
>> standard
>> i/o functions i can read the file but the output gives me \1071 ... instead 
>> of
>> the unicode characters. 

JM> Jhc does all of its IO in utf8. CharIO is a drop in replacement for the
JM> standard prelude routines which converts everything to and from UTF8

JM> http://repetae.net/john/repos/jhc/CharIO.hs
JM> http://repetae.net/john/repos/jhc/UTF8.hs

btw, i plan to add this functionality to my Binary/Streams library,
basing on your code, John. so it will work something like:

unicode_stdout <- openWithEncoding unicode stdout
vPutStrLn unicode_stdout "it's a test"

i have the question about this issue - i also want to provide
autodetection mechanism, which relies on first bytes of text files to
set proper encoding. what is the standard rules to encode utf8/utf16
encoding used for text in file in these first bytes?



-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]



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


[Haskell-cafe] Re: hPutStrLn and hFlush

2006-01-10 Thread Simon Marlow

John Meacham wrote:

Yeah. this is a major bug in ghc IMHO. I believe it has been fixed, but
am unsure.


It hasn't been fixed, this is the current behaviour and it's likely to 
stay that way, I'm afraid.


We used to run finalizers on exit, but we stopped doing that for various 
reasons.  Even when we did run finalizers on exit, we couldn't guarantee 
to run all of them.



Since we can't rely on finalizers to run in general, some
sort of 'atexit' routine is needed. (which would be a good addition to
the standard libraries anyway)


You can implement atexit quite straightforwardly, if that's what you want.

exits = unsafePerformIO (newIORef []) :: IORef [IO ()]
main = do_stuff `finally` (readIORef exits >>= sequence_ . reverse)
atexit io = modifyIORef exits (io:)

In reality you probably want to use weak pointers here.  Using this 
version of atexit to close Handles is bad, because it holds on to the 
Handle until the end of the program.  Better to use a Weak pointer and 
allow the Handle to be GC'd, but then you still need finalizers.


Cheers,
Simon

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


[Haskell-cafe] Haskell DB bindings

2006-01-10 Thread oleg

[moved from the main Haskell-list: I'm afraid the HDB discussion on
the Haskell mailing list had already been long]

Tim Docker wrote on the Haskell mailing list

> The differences between HDBC and HSQL have been recently discussed.
> Where does Takusen fit into this picture? From the above, it sounds
> like it has quite a different API. Are all 3 of these actively
> maintained?

Takusen is built around an enumerator -- left fold enumerator, to be
precise. That is, a database query is considered to be `left-folding'
over the result table. Early termination is supported -- the iteration
can be finished at any time the iteratee decided it has had
enough. Cursors -- derivatives (pun intended) of the enumerator -- are
supported as well, and we have a withCursor function (although, due to
laziness, we haven't implemented the type-based region management for
cursors. But we have talked about it!)

The best supported databases are Oracle and Sqlite. For them, we
implement buffer pre-allocation, pre-fetching (useful for minimizing
the communication overhead if rows are small), parameter binding,
handling date-time datatypes.  Parameter binding is not yet supported
for PostgreSQL.

All interfaces support DML/DDL statements, transactions and isolation
modes (if the back-end supports that), transparent translation from
the DB type to a Haskell type. The user doesn't need to do anything
for the translation. Database NULLs are fully handled: if the Haskell
datatype is a Maybe datatype, NULL is permitted and translated into
Nothing. Otherwise, NULL raises an exception. Nulls are distinguished 
from empty strings, provided the database server does so.

Takusen has two layers. The low-level API (which is not actually meant
for the end user) reconciles the differences among various DB
interfaces. Currently supported are Oracle, Sqlite, PostgreSQL, Stub
(that is, no DB -- useful for testing), and the ntwdblib interface to
MSSqlServer (Microsoft encourages a newer interface though).

Krasimir Angelov wrote:
> Can you explain how do you manage the lifetime of handles in Takusen?
> It isn't clear to me where are the advantages of enumerators.

The handles are not visible to the user. The user cannot close the
handle (or forget to close the handle) because the user is not given
the handle in the first place. Just as we left-fold over a list, we
are not given the pointer to the ``current list''. We are merely given
the current element of the list. Perhaps the following links might be
of help:

 http://www.eros-os.org/pipermail/e-lang/2004-March/009643.html
 http://pobox.com/~oleg/ftp/Haskell/misc.html#fold-stream
 http://pobox.com/~oleg/ftp/papers/LL3-collections-enumerators.txt
 
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe