John Meacham | 1 Aug 2003 01:36
Favicon

Re: Text I/O library proposal, first draft

presumably if you are doing random access on the file, it is in a known
nonarbitrary text encoding (like utf8). in which case you can
read/access the file with the binary routines and just use the
appropriate text conversions to get data out. 
        John

On Thu, Jul 31, 2003 at 03:55:44PM -0700, Hal Daume wrote:
> Hi Ben,
> 
> > Bad things:
> > 
> >   * There's no way to implement fgetpos/fsetpos type functionality,
> >     because coders don't expose their internal state. (In fact, there
> >     would need to be a way to explicitly copy the state, since it may
> >     well include IORefs, Ptrs, etc.) Is this a serious problem?
> 
> Yes!  This is an enormously serious problem.  At least for me.
> 
> It's not a problem for writing files, but I really really really need
> this functionality when reading files.  Reason: I'm often tooling around
> in very large (1gb or greater) files which happen to be sorted on some
> sort of index and I need to do binary search in them.  To load all the
> file into Haskell or to do linear search is impossible.
> 
> Other than that, I rather like the design.
> 
>  - Hal
> -- 
> Haskell mailing list
> Haskell <at> haskell.org
(Continue reading)

oleg | 1 Aug 2003 04:15
Picon
Favicon

*safe* coerce, for regular and existential types


This message describes functions safeCast and sAFECoerce implemented
in Haskell98 with common, pure extensions. The functions can be used
to 'escape' from or to existential quantification and to make
existentially-quantified datatypes far easier to deal with. Unlike
Dynamic, the present approach is pure, avoids unsafeCoerce and
unsafePerformIO, and permits arbitrary multiple user-defined typeheaps
(finite maps from types to integers and values).

An earlier message [1] introduced finite type maps for
purely-functional conversion of monomorphic types to unique
integers. The solution specifically did not rely on Dynamic and
therefore is free from unsafePerformIO. This message shows that the
type maps can be used for a safe cast, in particular, for laundering
existential types. The code in this message does NOT use
unsafePerformIO or unsafeCoerce. To implement safe casts, we define a
function sAFECoerce -- which works just like its impure
counterpart. However the former is pure and safe. sAFECoerce is a
library function expressed in Haskell with common extension. The
safety of sAFECoerce is guaranteed by the typechecker itself.

This whole message is self-contained, and can be loaded as it is in
GHCi, given the flags
  -fglasgow-exts -fallow-undecidable-instances -fallow-overlapping-instances

This message was inspired by Amr Sabry's problem on existentials.  In
fact, it answers an unstated question in Amr Sabry's original message.

It has been observed on this list that existentially-quantified
datatypes are not easy to deal with [2]. For example, suppose we have
(Continue reading)

Glynn Clements | 1 Aug 2003 07:03
Favicon

Re: Text I/O library proposal, first draft


Ben Rudiak-Gould wrote:

> module System.TextIOFirstDraft (...) where
> 
> -- A BlockRecoder takes source and destination buffers and does some sort
> -- of translation between them. It returns the number of values (not
> -- bytes!) consumed and the number of values produced. It does not have to
> -- empty the input buffer or fill the output buffer on each call, but it
> -- must do something (i.e. it's not acceptable to return (0,0)). Coders
> -- will in general have internal state which is updated on each call.

It would be preferable if this wasn't all within the IO monad. It
shouldn't be necessary, even for stateful encodings.

--

-- 
Glynn Clements <glynn.clements <at> virgin.net>
Derek Elkins | 1 Aug 2003 07:38

Re: *safe* coerce, for regular and existential types

Throughout this message you imply, if not outright state, that Dynamics
requires unsafeCoerce/unsafePerformIO.  This is simply not the case. 
GHC implements Dynamics with unsafeCoerce, or did last time I checked,
but it can easily be implemented using only existentials. (I presume
that this decision was made either for efficiency, simplicity, and/or
simply that another (readily useable) technique was not known when the
library was made.)

Anyways, as I have often mentioned, "A Lightweight Implementation of
Generics and Dynamics" has an unsafePerformIO/Coerce free implementation
of Dynamics as well as Generics as the title suggests.
Manuel M T Chakravarty | 1 Aug 2003 08:59
Picon
Picon
Favicon
Gravatar

ANN: H98 FFI Addendum 1.0, Release Candidate 12

Dear Haskell Folks,

Release Candidate 12 of the H98 FFI Addendum 1.0 is now
available from

  http://www.cse.unsw.edu.au/~chak/haskell/ffi/

Since the release of RC 11 (12 June), there was only one
small change (which was already under discussion before RC
11 was published).  Hence, I consider Version 1.0 of the FFI
Addendum to be completed; no changes except linguistic ones
and plain error corrections will be accepted anymore for
this version.

Cheers,
Manuel

-=-

Changes since RC11:
* 5.5: Swapped argument order of `newForeignPtr' and `addForeignPtrFinalizer'

Note to FFI people, there were at least three votes
(Alastair, Sven, and me) for this change and none against.
Peter Thiemann | 1 Aug 2003 09:44
Picon
Favicon

Use of H98 FFI

I recently had my first exposure to Haskell's FFI when I was trying to
compute MD5 and SHA1 hashes using the existing C implementations. In
each case, the idea is to make the hash function available as function

> md5 :: String -> String

However, the naive implementation

>     md5_init md5_state
>     n <- newCString str
>     md5_append md5_state n (fromIntegral (length str))
>     md5_finish md5_state md5_digest

does not scale to computing hashes of really long strings (50 MB, say,
as arising from reading a moderately big file), since it tries to
create a CString of that size, first! 

Trying to avoid the allocation of this giant CString requires to split
up the original string into smaller parts and convert each part to a
CString separately. Clearly, this task involves a lot of allocation,
essentially the input string needs to be copied part by part.

Hence, I was wondering why the FFI only provides functionality to
convert an *entire* list of Char into a CString. For applications like
this hash computation, it would be advantageous to be able to specify
*how much* of the input string to marshall to the CString and have the
conversion function return the rest of the input string and the
CString. That is, in addition to 

> newCString :: String -> IO CString
(Continue reading)

Sven Panne | 1 Aug 2003 10:11
Picon

Re: Use of H98 FFI

Peter Thiemann wrote:
>>md5 :: String -> String

Hmmm, this should probably be:

 > md5 :: [Word8] -> [Word8]

unless you really want the MD5 of the Unicode characters...

Cheers,
    S.
Derek Elkins | 1 Aug 2003 10:23

Re: Use of H98 FFI

On 01 Aug 2003 09:44:14 +0200
Peter Thiemann <thiemann <at> informatik.uni-freiburg.de> wrote:

> I recently had my first exposure to Haskell's FFI when I was trying to
> compute MD5 and SHA1 hashes using the existing C implementations. In
> each case, the idea is to make the hash function available as function
> 
> > md5 :: String -> String
> 
> However, the naive implementation
> 
> >     md5_init md5_state
> >     n <- newCString str
> >     md5_append md5_state n (fromIntegral (length str))
> >     md5_finish md5_state md5_digest
> 
> does not scale to computing hashes of really long strings (50 MB, say,
> as arising from reading a moderately big file), since it tries to
> create a CString of that size, first! 
> 
> Trying to avoid the allocation of this giant CString requires to split
> up the original string into smaller parts and convert each part to a
> CString separately. Clearly, this task involves a lot of allocation,
> essentially the input string needs to be copied part by part.
> 
> Hence, I was wondering why the FFI only provides functionality to
> convert an *entire* list of Char into a CString. For applications like
> this hash computation, it would be advantageous to be able to specify
> *how much* of the input string to marshall to the CString and have the
> conversion function return the rest of the input string and the
(Continue reading)

Ralf Laemmel | 1 Aug 2003 11:23
Picon
Picon
Favicon

Re: *safe* coerce, for regular and existential types

oleg <at> pobox.com wrote:
> 
> ... loads of cunning stuff omitted 
>

Software-engineering-wise your approach suffers
from an important weakness: a closed world assumption.
The programmer has to maintain your "TI" and pass it
on in all kinds of contexts for the array of types to
be handled. I also had a type-safe and efficient cast
in [1] with a CWA. (I guess it works fine for
extensials.) My CWA was even more serious however.
I use a class for casting whose declaration even
depends on the array of types to be handled. On the
positive side, I didn't need undecidable not even
overlapping instances. Also, the programmer is not
concerned with passing on any type seq like your
"TI". I really admire your use of polymorphic lists
(which are in fact kind of products) to get the
problem of type sequences to the value level. Cool!

Do you see any way to effectively remove this CWA?
(Only then it could serve as a replacement of the
current cast function.) If yes, would you expect that
your approach is more efficient then the one taken in
Data.Typeable? (We recently split up Data.Dynamics
into Data.Dynamics and a more primitive module
Data.Typeable which contains cast; see CVS) Is it obvious
to see that fetching stuff from the type sequences would
be indeed efficient for long PLists? Well, I guess the
(Continue reading)

Tomasz Zielonka | 1 Aug 2003 12:02
Picon
Picon
Favicon

Re: a breaking monad

On Thu, Jul 31, 2003 at 05:15:33PM -0400, Derek Elkins wrote:
> On Thu, 31 Jul 2003 13:18:40 -0700
> "Hal Daume" <t-hald <at> microsoft.com> wrote:
> 
> > so, my questions are: does this exist in some other form I'm not aware
> > of?  is there something fundamentally broken about this (sorry for the
> > pun)?  any other comments, suggestions?
> 
> This looks like a bizarre rendition of the Error/Exception monad.
> 
> I believe the function "breakable" would be fairly accurately
> represented with '\b -> runErrorT b >>= either return return' and use
> throwError for break.

I used the Cont(inuation) monad for similar purposes. This has an
advantage that you can choose a place to break (jump?) into, each place
having a possibly different type of return value.

Here's an example:

  module A where

  import Control.Monad.Cont
  import Control.Monad

  fun :: IO ()
  fun = (`runContT` return) $ do
      r <- callCC $ \exit -> do
	  r1 <- callCC $ \exit1 -> do
	      r2 <- callCC $ \exit2 -> do
(Continue reading)


Gmane