[Haskell-cafe] Re: Problematic irrefutable pattern matching of existentials

2006-10-01 Thread Ross Paterson
On Sun, Oct 01, 2006 at 08:05:15PM -0700, [EMAIL PROTECTED] wrote:
> I have come to realize that irrefutable pattern matching of
> existentials may indeed be problematic. Let us consider the following
> existential data type
> 
> > data FE = forall a. Typeable a => Foo a
> >   | forall a. Typeable a => Bar a
> 
> The following tests type and run (the latter raising the expected
> exception).
> 
> > test1 = case (Foo ()) of Foo x -> show $ typeOf x
> > test2 = case (Bar True) of Foo x -> show $ typeOf x
> 
> Let us suppose that irrefutable pattern matching of existentials is
> allowed. What would be the value of the expression
> 
>   case (Bar True) of ~(Foo x) -> show $ typeOf x
> then?
> 
> Hopefully not "Bool". One might say that the expression ought to bottom
> out. However, what reason one may give for that outcome? The only
> binding in the above expression is of 'x', whose value is never
> demanded. Indeed, "show $ typeOf (undefined :: ())" yields the
> non-bottom value "()". 

There is also the implicit dictionary argument of typeOf, and this is
demanded, so the value should be _|_.

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


[Haskell-cafe] Problematic irrefutable pattern matching of existentials

2006-10-01 Thread oleg

I have come to realize that irrefutable pattern matching of
existentials may indeed be problematic. Let us consider the following
existential data type

> data FE = forall a. Typeable a => Foo a
> | forall a. Typeable a => Bar a

The following tests type and run (the latter raising the expected
exception).

> test1 = case (Foo ()) of Foo x -> show $ typeOf x
> test2 = case (Bar True) of Foo x -> show $ typeOf x

Let us suppose that irrefutable pattern matching of existentials is
allowed. What would be the value of the expression

case (Bar True) of ~(Foo x) -> show $ typeOf x
then?

Hopefully not "Bool". One might say that the expression ought to bottom
out. However, what reason one may give for that outcome? The only
binding in the above expression is of 'x', whose value is never
demanded. Indeed, "show $ typeOf (undefined :: ())" yields the
non-bottom value "()". 

One may claim that the existential pattern match also binds an
implicit dictionary argument, which is demanded above. That
explanation is quite unsatisfactory, because it breaks the abstraction
of type classes. The dictionary passing is merely an _implementation
technique_ for type classes. Furthermore, it is not the only 
implementation technique: JHC and Chameleon, for example, use
intensional type analysis to implement typeclasses.


On a different note, Conor McBride wrote:
> It isn't necessary to perform
> constructor discrimination when it's statically known that exactly one
> constructor is possible, so those patterns can always be made
> irrefutable, with matching replaced by projection.

that is, in essence, the idea behind 
`Tagless Staged Interpreters for Typed Languages'
Pasalic, Taha, Sheard: ICFP02
It is well-written paper, with an excellent introduction and
motivation.

Incidentally, one can write their tagless staged interpreter in Haskell
as it is. No dependent types are necessary.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: How would you replace a field in a CSV file?

2006-10-01 Thread Pete Kazmier
[EMAIL PROTECTED] writes:

> For such a small self-contained task, I don't think Haskell
> is any better than Python.

I figured as much, but I thought with the new FPS lazy bytestrings it
might have a chance in terms of raw speed.  On the other side of the
coin, in terms of elegance, I thought I'd ask as haskellers always
amaze me with their one-liners :-)

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


Re: [Haskell-cafe] non lazy io

2006-10-01 Thread Neil Mitchell

Hi,


I would like a non-lazy alternative to

readFile

is there such a thing in the libraries?


Not as far as I know, but you can achieve something similar by doing:

-- untested
readFile' file = do
  src <- readFile file
  return $ seq (length src) src

What is the particular reason you want a strict readFile for?

Thanks

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


[Haskell-cafe] non lazy io

2006-10-01 Thread Matt Roberts

I would like a non-lazy alternative to

readFile

is there such a thing in the libraries?

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


[Haskell-cafe] How would you replace a field in a CSV file?

2006-10-01 Thread tpledger
Hi Pete.

For such a small self-contained task, I don't think Haskell
is any better than Python.

Haskell would come into its own if you wanted some assurance
about type safety, and/or were taking on a task large enough
to warrant the use of records (and hence record update
notation).

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


[Haskell-cafe] OOHaskell problems

2006-10-01 Thread Jason Dagit

Hello,

I wanted to try using OOHaskell as a library, but I've run into some
problems I don't understand.

I downloaded the copy from:
http://homepages.cwi.nl/~ralf/OOHaskell/

In the HList subdirectory I created a .cabal file which exposes as
many of the modules in HList as I could.  I then installed the HList
library using cabal.  Back in the main OOHaskell directory I created a
.cabal file for OOHaskell which depended on the newly installed HList
library.

The OOHaskell library exposes the modules:
DeepNarrow
New
Nominal
OOHaskell

After I installed the OOHaskell library I ran:
ghc --make -package OOHaskell -package HList SimpleIO.hs
Chasing modules from: SimpleIO.hs
Compiling Nominal  ( ./Nominal.hs, ./Nominal.o )
Compiling New  ( ./New.hs, ./New.o )
Compiling DeepNarrow   ( ./DeepNarrow.hs, ./DeepNarrow.o )
Compiling OOHaskell( ./OOHaskell.hs, ./OOHaskell.o )
Compiling SimpleIO ( SimpleIO.hs, SimpleIO.o )

SimpleIO.hs:44:11:
   No instance for (HasField (Proxy Field1) HNil v)
 arising from use of `foo' at SimpleIO.hs:44:11-13
   Probable fix: add an instance declaration for (HasField (Proxy
Field1) HNil v)
   In the definition of `testfoo':
   testfoo = foo ((field1 .=. True) .*. emptyRecord)

SimpleIO.hs:116:7:
   No instance for (HasField (Proxy MoveX) HNil (a -> IO t))
 arising from use of `#' at SimpleIO.hs:116:7
   Probable fix:
 add an instance declaration for (HasField (Proxy MoveX) HNil (a -> IO t))
   In the first argument of `($)', namely `p # moveX'
   In a 'do' expression: (p # moveX) $ 3
   In the definition of `myFirstOOP':
   myFirstOOP = do
  p <- point
  (p # getX) >>= System.IO.print
  (p # moveX) $ 3
  (p # getX) >>= System.IO.print

SimpleIO.hs:124:19:
   No instance for (HasField (Proxy MutableX) HNil (IORef a))
 arising from use of `#' at SimpleIO.hs:124:19
   Probable fix:
 add an instance declaration for (HasField (Proxy MutableX) HNil (IORef a))
   In the first argument of `writeIORef', namely `(p # mutableX)'
   In a 'do' expression: writeIORef (p # mutableX) 42
   In the definition of `mySecondOOP':
   mySecondOOP = do
   p <- point
   writeIORef (p # mutableX) 42
   (p # getX) >>= System.IO.print

SimpleIO.hs:177:23:
   No instance for (HasField (Proxy GetX) HNil (IO a))
 arising from use of `#' at SimpleIO.hs:177:23
   Probable fix:
 add an instance declaration for (HasField (Proxy GetX) HNil (IO a))
   In the second argument of `(>>=)', namely `(# getX)'
   In the first argument of `(>>=)', namely `localClass >>= ((# getX))'
   In the result of a 'do' expression:
   (localClass >>= ((# getX))) >>= System.IO.print

SimpleIO.hs:225:8:
   No instance for (HasField (Proxy GetOffset) HNil (IO a))
 arising from use of `#' at SimpleIO.hs:225:8
   Probable fix:
 add an instance declaration for (HasField (Proxy GetOffset) HNil (IO a))
   In the first argument of `(>>=)', namely `p # getOffset'
   In the result of a 'do' expression: (p # getOffset) >>= System.IO.print
   In the definition of `testPara':
   testPara = do
p <- para_point 1
(p # getX) >>= System.IO.print
(p # moveX) $ 2
(p # getX) >>= System.IO.print
(p # getOffset) >>= System.IO.print

To investigate this further, in the OOHaskell directory I typed:
$ ghci -fglasgow-exts -fallow-overlapping-instances
-fallow-undecidable-instances -i./HList ShapesLub.hs   ___ ___
_
 / _ \ /\  /\/ __(_)
/ /_\// /_/ / /  | |  GHC Interactive, version 6.4.2, for Haskell 98.
/ /_\\/ __  / /___| |  http://www.haskell.org/ghc/
\/\/ /_/\/|_|  Type :? for help.

Loading package base-1.0 ... linking ... done.
Compiling FakePrelude  ( ./HList/FakePrelude.hs, interpreted )
Compiling HListPrelude ( ./HList/HListPrelude.hs, interpreted )
Compiling GhcExperiments   ( ./HList/GhcExperiments.hs, interpreted )
Compiling HArray   ( ./HList/HArray.hs, interpreted )
Compiling HZip ( ./HList/HZip.hs, interpreted )
Compiling HOccurs  ( ./HList/HOccurs.hs, interpreted )
Compiling HTypeIndexed ( ./HList/HTypeIndexed.hs, interpreted )
Compiling Record   ( ./HList/Record.hs, interpreted )
Compiling GhcRecord( ./HList/GhcRecord.hs, interpreted )
Compiling Label4   ( ./HList/Label4.hs, interpreted )
Compiling New  ( ./New.hs, interpreted )
Compiling TIP  ( ./HList/TIP.hs, interpreted )
Compiling TIC  ( ./HList/TIC.hs, interpreted )
Compiling GhcSyntax( ./HList/GhcSyntax.hs, interpreted )
Compiling TypeCastGeneric1 ( ./HList/TypeCastGeneric1.hs, interpreted )
Compiling TypeEqBoolGeneric ( ./HList/TypeEqBoolGeneric.hs, interpreted )
Compiling TypeEqGeneric1   ( ./HList/TypeEqGeneric1.hs, interpreted 

[Haskell-cafe] question - which monad to use?

2006-10-01 Thread Tamas K Papp
Hi,

I have a computation where a function is always applied to the
previous result.  However, this function may not return a value (it
involves finding a root numerically, and there may be no zero on the
interval).  The whole problem has a parameter c0, and the function is
also parametrized by the number of steps that have been taken
previously.

To make things concrete,

type Failmessage = Int  -- this might be something more complex
data Result a = Root a | Failure Failmessage -- guess I could use Either too

f :: Double -> Int -> Double 0 -> Result Double
f c0 0 _ = c0
f c0 j x = {- computation using x, parameters calculated from c0 and j -}

Then

c1 = f c0 0 c0
c2 = f c0 1 c1
c3 = f c0 2 c2
...

up to cn.

I would like to

1) stop the computation when a Failure occurs, and store that failure

2) keep track of intermediate results up to the point of failure, ie
have a list [c1,c2,c3,...] at the end, which would go to cn in the
ideal case of no failure.

I think that a monad would be the cleanest way to do this.  I think I
could try writing one (it would be a good exercise, I haven't written
a monad before).  I would like to know if there is a predefined one
which would work.

Thank you,

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


[Haskell-cafe] How would you replace a field in a CSV file?

2006-10-01 Thread Pete Kazmier
The other day at work an opportunity arose where I was hoping to sneak
some Haskell into the pipeline of tools used to process call detail
records (CDRs).  In the telecommunications industry, CDRs are used for
billing.  Each CDR is a single line record of 30 comma-separated
values.  Each line is approximately 240 characters in length.  The
task at hand is to replace field number 10 if a new value can be found
in a hashmap which is keyed using the contents of the field.

My colleague was going to write a C program (that's all he knows), but
I whipped up a trivial python program instead.  I was curious if a
haskell version could be faster and more elegant , but I have not been
able to beat my python version in either case.  So, I'm curious as to
how you would go about this task in Haskell.  The input files are
generally 300-400MB, and the hashmap will contain perhaps 20-30 items.

For those that know python, here is a very simple implementation that
happens to be very fast compared to my Haskell version and very short:

for line in sys.stdin:
fields = line.split(',')
fields[9] = tgmap.get(fields[9], fields[9])
print ",".join(fields),

For each line in standard input:

  - Splits the string on the comma: "field0,field1,...,field29" => 
["field0", "field1", ..., "field29"] to obtain a list of strings.

  - Gets the value associated with the key of field9 from tgmap, if it
does not exist, it returns a default value which is the original
value.  I.e., if it's not in the map, then don't replace the
field.

  - Joins the list of fields with a comma to yield a string again
which is printed out to standard output.  The join method on the
string is a bit odd: ",".join([1,2,3]) => "1,2,3"

Here is my first Haskell attempt:

import Data.ByteString.Lazy.Char8 as B hiding (map,foldr)
import Data.List (map)
import Data.Map as M hiding (map)

-- This is just a placeholder until I actually populate the map
tgmap = M.singleton (B.pack "Pete") (B.pack "Kazmier")

main = B.interact $ B.unlines . map doline . B.lines
where doline= B.join comma . mapIndex fixup . B.split ','
  fixup i s = if i==9 then M.findWithDefault s s tgmap else s
  comma = B.pack ","

-- f is supplied the index of the current element being processed
mapIndex f xs = m f 0 xs
where m f i [] = []
  m f i (x:xs') = f i x : m f (i+1) xs'

After talking with dons on #haskell, he cleaned my version up and
produced this version which gets rid of 'if' statement and makes
mapIndex stricter:

import Data.ByteString.Lazy.Char8 as B hiding (map,foldr)
import Data.List (map)
import Data.Map as M hiding (map)

-- This will be populated from a file
dict = M.singleton (B.pack "Pete") (B.pack "Kazmier")

main = B.interact $ B.unlines . map doline . B.lines
where doline= B.join comma . mapIndex fixup . B.split ','
  comma = B.singleton ','
  fixup 3 s = M.findWithDefault s s dict
  fixup n s = s

-- f is supplied the index of the current element being processed
mapIndex :: (Int -> ByteString -> ByteString) -> [ByteString] ->
[ByteString]
mapIndex f xs = m xs 0
where m []  _ = []
  m (x:xs') i = f i x : (m xs' $! i+1)

That helped things a bit, but I must confess I don't understand how
the strictness improved things as I had assumed things were going to
be evaluated in a reasonable amount of time due to the printing of
output.  I thought IO was interlaced with the execution and thus I
wasn't going to have to concern myself over laziness.  In addition,
the function is able to generate new elements of the list on demand so
I thought it was a good citizen in the lazy world.  Could anyone help
explain?

And then he came up with another version to avoid the 'unlines', but
that did not that really speed things up significantly.  So, with all
that said, is there a better approach to this problem?  Perhaps a more
elegant Haskell solution?

Thanks,
Pete

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


[Haskell-cafe] Re: [Offtopic] Re: Re: A better syntax for qualified operators?

2006-10-01 Thread Benjamin Franksen
Cale Gibbard wrote:

>> "What a beautiful world this could be..." ;-)) (*)
>>
>> Cheers,
>> Ben
>> (*) Donald Fagen (forgot the name of the song)
> 
> I think I.G.Y. (International Geophysical Year) is it:
> 
> On that train all graphite and glitter
> Undersea by rail
> Ninety minutes from New York to Paris
> (More leisure time for artists everywhere)
> A just machine to make big decisions
> Programmed by fellows with compassion and vision
> We'll be clean when their work is done
> We'll be eternally free yes and eternally young
> 
> What a beautiful world this will be
> What a glorious time to be free

Many thanks for digging it out. Hey, it fits some of the discussions on this
list even better than I remembered ;-)

Cheers,
Ben

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


[Haskell-cafe] Re: irrefutable patterns for existential types / GADTs

2006-10-01 Thread apfelmus
> Thanks for asking!
> [...]
> Online algorithms do look like a good place to try to get some leverage
> from this, but we haven't really been in a position to experiment so
> far. I'm sure that will change. 

Well, I asked because laziness with memoization gives a definite edge in
terms of algorithmic time complexity over strictness (proved for online
algorithms in "more haste, less speed") and I wonder how this goes
together with totality and dependent types. A forthcoming ultimate
programming language should retain this edge, shouldn't it? ;-)


> It isn't necessary to perform
> constructor discrimination when it's statically known that exactly one
> constructor is possible, so those patterns can always be made
> irrefutable, with matching replaced by projection.

Thanks for pinpointing the culprit, because translated to GADTs, it
means that

"whenever we know from the type index that only one constructor is
possible, it can be made irrefutable."

So this is the kind of irrefutable pattern one could safely add. In
particular, this can be weakened to

"whenever we know the type index, i.e. there is no type refinement
depending on the value, an irrefutable pattern is safe."

But once no type refinement happens, the irrefutable pattern can already
be obtained via let bindings in existing Haskell! Below is a lazy
version of Bertram solution to the "Optimization problem" following
Ross' suggestions with existentials and GADTs:

> {-# OPTIONS_GHC -fglasgow-exts #-}
> 
> data Map s k a where
> Leaf :: Map () k a
> Node :: k -> a -> Map s k a -> Map t k a -> Map (s,t) k a

(Map s k a) is a tree which makes its structure explicit in the type
index s.

>
> unNode :: Map (s,t) k a -> (k,a,Map s k a, Map t k a)
> unNode (Node k a l r) = (k,a,l,r)

unNode knows the type index and is to be used for a lazy pattern match
  let (k,a,l,r) = unNode ..

> empty :: Map () k a
> empty = Leaf
> 
> member :: Ord k => k -> Map s k a -> Bool
> member _ Leaf= False
> member k (Node k' _ l r) = case compare k k' of
> LT -> member k l
> EQ -> True
> GT -> member k r
> 
> data Undoer s k a where
> Undoer :: (Map t k a) -> (Map t k a -> (a,Map s k a)) -> Undoer s k a

Undoer is just (exists t. ...) wrapped into a digestible type.

> -- insert key element blueprint map (blueprint, result, map)
> insert :: Ord k => k -> a -> Map s k a -> Undoer s k a
> insert k a Leaf = Undoer (Node k a Leaf Leaf)
> (\map -> let (_,a,_,_) = unNode map in (a,Leaf))

Note how the type system proves that the function (\map -> ..) always
has to expect (map) == Node ...
Then, unNode binds k',b',... /lazily/.
Same goes for the rest of insert:

> insert k a (Node k' b (l :: Map l k a) (r :: Map r k a) :: Map s k a)
> = case compare k k' of
> LT -> case insert k a l of
> Undoer (m :: Map t k a) f ->
> Undoer (Node k' b m r :: Map (t,r) k a)
> (\map -> let
> (k',b',m',r') = unNode map
> (a,l') = f m'
> in (a,Node k' b' l' r' :: Map s k a))
> EQ -> error "inserting existing element"
> GT -> case insert k a r of
> Undoer (m :: Map t k a) f ->
> Undoer (Node k' b l m :: Map (l,t) k a)
> (\map -> let
> (k',b',l',m') = unNode map
> (a,r') = f m'
> in (a,Node k' b' l' r' :: Map s k a))
> 
> -- update k fun blueprint map
> update :: Ord k => k -> (a -> a) -> Map s k a -> Map s k a -> Map s k a
> update k f (Node k' _ l' r') map = case compare k k' of
>   LT -> Node k' a (update k f l' l) r
>   EQ -> Node k' (f a) l r
>   GT -> Node k' a l (update k f r' r)
> where
> (_,a,l,r) = unNode map

Again a lazy pattern match on (map). Note that the type system enforces
that blueprint and actual (map) have the same shape s. The type
refinement for GADTs happens in the strict pattern match on the
blueprint and this allows us to lazily match the (map).

> splitSeq :: Ord a => [(a,b)] -> [(a,[b])]
> splitSeq = fst . splitSeq' empty
> 
> splitSeq' :: Ord a => Map s a [b] -> [(a,b)] -> ([(a,[b])], Map s a [b])
> splitSeq' bp [] = ([], bp)
> splitSeq' bp ((a,b):xs) = case member a bp of
> True -> let (l, m)  = splitSeq' bp xs in (l, update a (b:) bp m)
> _-> case insert a [] bp of
> Undoer bp' f -> let
> (rs,m)  = splitSeq' bp' xs
> (bs,m') = f m
> in ((a, b:bs) : rs, m')

To summarize, the problem can be solved without irrefutable patterns for
GADTs: the code above works for infinite lists. Yet, they are handy and
can be introduced safely in the case where the type indices are known in
advance and no type refinement happens.

Regards,
apfelmus

___
Haskell-Cafe mailing list
Haskell-Ca

[Haskell-cafe] Re: Why is type 'b' forced to be type 'm a' and not possibly 'm a -> m a'

2006-10-01 Thread tpledger
Vivian McPhail wrote:
...
> I need the arg a to be evaluated before it gets
> passed to a1 and a2. This definition does the right thing
> when type 'a' is a function type, because it is not a
> value, but with something like 'm a -> (m a -> m a) -> m
> a' with Forkable (a -> b) the first arg gets evaluated
> twice, to be more concrete:
>
> With
>
> (and golden white) eggs
>
> I want the 'eggs' that is passed to 'golden' to be the
> same as the 'eggs' that is passed to 'white', i.e.
...

Could you reduce the need for Forkable instances, by
rewriting '(and golden white) eggs' as 'and golden white =<<
eggs'?  Or would the same piece of code also have to handle
combinations such as monadic 'and golden white' and
non-monadic eggs?

[BTW, thanks for giving me a pretext to use the phrase
non-monadic eggs!]

> Tom suggested that I might be able to use the Reader monad
> , but I'm not clear as to how I could do this.

Please ignore that.  I only mentioned it in case the sole
purpose of fork was to propagate a String, which you've now
explained is not so.

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


[Haskell-cafe] Greetings...

2006-10-01 Thread tpledger
Seth Gordon wrote:
> I thought I should check and see if anyone
> on this list has used Haskell to munge a
> ten-million-row database table, and if
> there are any particular gotchas I should
> watch out for.

Are you sure you want to target the data directly?  Another
approach, that might have a better chance of a quick win
within your time frame, is to use Haskell to generate SQL
code.  That could still reduce the amount of code you
maintain by hand.

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


Re: [Haskell-cafe] Re: Greetings

2006-10-01 Thread Krasimir Angelov

On 10/1/06, Seth Gordon <[EMAIL PROTECTED]> wrote:

Paul Johnson wrote:
> I've done some stuff with maybe 50k rows at a time.  A few bits and pieces:
>
> 1: I've used HSQL
> (http://sourceforge.net/project/showfiles.php?group_id=65248) to talk to
> ODBC databases.  Works fine, but possibly a bit slowly.  I'm not sure
> where the delay is: it might just be the network I was running it over.
> One gotcha: the field function takes a field name, but its not random
> access.  Access the fields in query order or it crashes.

Thanks; that's certainly the sort of thing I like knowing in advance.


This behaviour depends on the underlying database. I remember that
MSSQL suffers from this disease. In addition with MSSQL you can't have
more than one opened dataset for a given connection. MySQL and
PostgreSQL doesn't have this problem. HSQL can't hide all differences
between the possible backends.


> 2: For large data sets laziness is your friend.  When reading files
> "getContents" presents an entire file as a list, but its really
> evaluated lazily.  This is implemented using unsafeInterleaveIO.  I've
> never used this, but in theory you should be able to set up a query that
> returns the entire database as a list and then step through it using
> lazy evaluation in the same way.

I assume that the collectRows function in HSQL can produce this kind of
a lazy list...right?


No. collectRows collects all records eagerly. The problem with the
lazy fetching is that you can close the database connection while your
lazy data sets aren't fetched yet. It is getting worse if you can't
have multiple opened data sets. If you still want lazy fetching you
can write a custom function like collectRows but using
unsafeInterleaveIO.


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


Re: [Haskell-cafe] Greetings...

2006-10-01 Thread Krasimir Angelov

On 10/1/06, Seth Gordon <[EMAIL PROTECTED]> wrote:

I'm planning to use HSQL, since it's in Debian stable and the API
resembles what I'm already familiar with.  Database access is slower
than file access (which is one reason I want to move as much logic as I
can out of SQL), so if the speed of getting rows out of the database
turns out to be the bottleneck in my code, I'll either be happy that all
the other code is so efficient or peeved that HSQL is so inefficient.


Hi Seth,

HSQL is just a thin wrapper around the underlying database engine. The
performance in this case depends mainly on the database engine that
you are using.

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