Re: [Haskell-cafe] FiniteMap-like module for unordered keys?

2004-11-10 Thread R. Turk
On Tue, Nov 09, 2004 at 11:41:49PM +, Jorge Adriano Aires wrote:
 Hello, 
 
  A hash-table becomes rather useless without mutable state AFAICS.
  Without it, one might almost just as well use a list of pairs...
 Could you please elaborate? Is there motive why an Hash Table, implemented as 
 FiniteMap of Lists, for instance, wouldn't be worth to using over a simple 
 List? (This wouldn't help G. Klyne of course). I've always wondered why a 
 non-monadic version of is not provided in the GHC libs... 
 
 J.A.

I assume you're talking about something like this:

{-# OPTIONS -fglasgow-exts #-}
{- I want a Hashable instance for String ;) -}
import Data.FiniteMap
import Data.HashTable (hashInt, hashString)
import Data.Int (Int32)

class Hashable a where hash :: a - Hash
instance Hashable Int where hash = hashInt
instance Hashable String where hash = hashString

type Hash = Int32
newtype HashTable a b = HT (FiniteMap Hash [b])

emptyHT :: HashTable a b
emptyHT = HT emptyFM

addToHT :: (Hashable a) = HashTable a b - a - b -
HashTable a b
addToHT (HT m) k v
= HT $ addToFM_C (flip (++)) m (hash k) [v]

Of course one could do that, and it would be (expected) O(log n)
instead of O(n), but I doubt I'd really call it a hashtable...
It's more like a variant on (Python's?) Decorate-Sort-Undecorate
pattern. (Replacing a direct comparison by a conversion to
something else which can be compared.) However, it could still be
usefull if there will be lots of lookups and comparing elements
is expensive.

Groetjes,
Remi
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Predicates in HaXml

2004-11-10 Thread Tom Spencer
Hi there,

In XSLT there is an XPath function that will let you select a
particular node in the current context, for example;
xsl:value-of select=team[1] / 
in Michael Kay's article
http://www-106.ibm.com/developerworks/xml/library/x-xslt/?article=xr

This selects the first team element in the current context. Is there a
work around to get similar functionality from the HaXml library?

Many Thanks
Tom Spencer
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


RE: [Haskell-cafe] One-shot? (was: Global variables and stuff)

2004-11-10 Thread Simon Marlow
On 09 November 2004 11:54, Graham Klyne wrote:

 I've not been following the Global variables debate too closely, it
 seeming to have something of a religious wars flavour, but I noticed
 that an example being proposed was how to achieve a one shot
 execution.  Here's something I did when working on modifications to
 the HaXML parser: 
 
 [[
 --  Memoization of withSocketsDo to prevent multiple calls.
 --  (cf. http://tangentsoft.net/wskfaq/articles/lame-list.html)
 socketsInitialized :: Bool
 socketsInitialized = unsafePerformIO ( withSocketsDo ( return True ) )
 ]]
 
 Does it work as I think it does?  ARe there any problems I'm
 overlooking? 

You should add {-# NOINLINE socketsInitialized #-} to be on the safe
side, but in practice GHC won't inline it anyway.  The pragma would be
good documentation though.

Cheers,
Simon
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Predicates in HaXml

2004-11-10 Thread Malcolm Wallace
Tom Spencer [EMAIL PROTECTED] writes:

 In XSLT there is an XPath function that will let you select a
 particular node in the current context, for example;
 xsl:value-of select=team[1] / 
 
 This selects the first team element in the current context. Is there a
 work around to get similar functionality from the HaXml library?

It's easy to define, yes.  Here is an indexing combinator that
chooses one result of a CFilter, based on numeric position:

index :: Int - CFilter - CFilter
index n f = (\c- [ (f c)!!n ])

So for your example, you want to write something like:

index 0 (tag team) `o` children

This is probably the simplest way of doing your specific task, but
there are of course other ways.  The tool Xtract has a parser for
XPath-like expressions, including more complex predicates, which get
translated directly to combinator-style accessors.  Unfortunately,
the set of combinators used in Xtract is slightly different from
those in the rest of HaXml, but they bear a close relationship.

You could also use LabelFilters, e.g.

(\cs- ... cs!!0 ...) `oo` numbered (tag team `o` children)

and doubtless there are other techniques too.

Regards,
Malcolm
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Space efficiency problem

2004-11-10 Thread Keith Wansbrough
 Hi,
 
 This may be silly, but I tried to code a simmulated annealing method
 to solve the travelling salesman prblem, by adapting the algorithm
 described in Numerical Recipes in C.

Doesn't seem silly so far! :-)

 The problem is that there are
 so many iterations, that the program gets killed (kill -9) by the
 system.

I'm not sure what you mean here - I've never encountered a system that
kills processes with -9, other than at shutdown time.  Are you sure
it's -9?

How do you know it's because there are too many iterations?

 I use the State monad to code the optimisation algorithm,
 and a simple configurations generator for generating the each
 path. After profiling with -hc, the heap profile shows that the
 top-level function of the algorithm uses about 40Mb of heap space.

That sounds fine to me - I have plenty of programs that use well over
100MB of heap.  How much memory do you have?  (you say later that it
eats up all the available space - I find it hard to believe 40MB is
all you have!).

 How can I improve this awful program?

You probably have a space leak.  This is usually caused by p or f not
forcing the evaluation of all of m0.  Since the next m0 depends on the
previous one, and so on, this causes all values of m0 to be held in
the heap until the end of the program.

Add strictness annotations in the right places[*] until heap usage is
constant, rather than increasing with each iteration.

 untilM :: (Monad m) = (m a - m Bool) - (a - m a) - m a - m a
 untilM p f m0 = do
   isOver - p m0
   if isOver then m0
 else untilM p f (m0 = f)

[*] of course, this is an entirely non-trivial task, and involves art
as well as skill...

Hope this helps.

Cheers,

--KW 8-)
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] One-shot? (was: Global variables and stuff)

2004-11-10 Thread Keean Schupke
I have written a small library for supporting one-shot without using 
unsfePerformIO...
The library uses SYSV semaphores under linux to make sure the functional 
argument of
once is only ever run once. It uses the ProcessID as the key for the 
semaphore, so will
even enforce the once-only property accross different Haskell threads. 
Some semaphore
functions are also exported, allowing other constraints to be used (for 
example, once
only over multiple processes by using a constant ID rather than the 
processID.

I have attached the source for the library incase anyone is interested. 
If people think
it is useful I could put it up on a website (let me know). Also attached 
is an example,
which can be compiled with:

   ghc -o test NamedSem.hs Test.hs -package posix
   Keean.
{-# OPTIONS -fffi #-}

module NamedSem(once,NamedSem,openNamedSem,closeNamedSem,tasNamedSem) where

import IO
import Foreign.C.Types
import Foreign.Ptr
import Foreign.Storable
import System.Posix.Process

foreign import ccall wrapper mkCallback :: IO CInt - IO (FunPtr (IO CInt))
foreign import ccall unsafe stdlib.h malloc mallocSemOp :: CInt - IO (Ptr SemOp)
foreign import ccall unsafe stdlib.h free freeSemOp :: Ptr SemOp - IO ()
foreign import ccall unsafe stdlib.h atexit atexit :: FunPtr (IO CInt) - IO ()
foreign import ccall unsafe sys/sem.h semget semget :: CInt - CInt - CInt - IO CInt
foreign import ccall unsafe sys/sem.h semop semop :: CInt - Ptr SemOp - CInt - IO CInt
foreign import ccall unsafe sys/sem.h semctl semctl :: CInt - CInt - CInt - IO CInt

data NamedSem = NamedSem CInt deriving Show
data SemOp = SemOp CShort CShort CShort

instance Storable SemOp where
	peek p = do { n - peekByteOff p 0; o - peekByteOff p 2; f - peekByteOff p 4; return (SemOp n o f) }
	poke p (SemOp n o f) = do { pokeByteOff p 0 n; pokeByteOff p 2 o; pokeByteOff p 4 f }
	sizeOf _ = 6
	alignment _ = 2

atExit :: IO CInt - IO ()
atExit f = do { g - mkCallback f; atexit g }

openNamedSem :: Int - IO (Maybe NamedSem)
openNamedSem n = do
	id - semget (fromIntegral n) 1 0o1660
	if id = 0
		then do { atExit (semctl id 0 0); return $ Just (NamedSem id) }
		else return $ Nothing

closeNamedSem :: NamedSem - IO ()
closeNamedSem (NamedSem id) = do
	_ - semctl id 0 0 -- remove semaphore set
	return ()

copySemOpList :: Ptr SemOp - [SemOp] - IO Int
copySemOpList op = foldl
	(\a b - do { i - a; pokeElemOff op i b; return (i+1) })
	(return 0)

applySemOpList :: NamedSem - [SemOp] - IO Bool
applySemOpList (NamedSem id) ol@(o0:_) = bracket
	(mallocSemOp $ fromIntegral $ sizeOf o0 * length ol)
	freeSemOp $ \op - do
		i - copySemOpList op ol
		j - semop id op (fromIntegral i)
		return (j = 0)

tasNamedSem :: NamedSem - IO Bool
tasNamedSem ns = applySemOpList ns [
		SemOp 0 0 0o4000,	-- test for zero
		SemOp 0 1 0			-- add 1 to semaphore
	]

once :: IO () - IO ()
once f = do
	i - getProcessID
	s - openNamedSem (fromIntegral i)
	case s of
		Just n - do
			b - tasNamedSem n
			if b then f else return ()
		_ - error unable to get semaphore

{-# OPTIONS -fglasgow-exts #-}

module Main where

import NamedSem

test :: IO ()
test = once $ putStrLn testing

main :: IO ()
main = do
	test
	test
	test
	test
	test
	test
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Space efficiency problem

2004-11-10 Thread Glynn Clements

Keith Wansbrough wrote:

  The problem is that there are
  so many iterations, that the program gets killed (kill -9) by the
  system.
 
 I'm not sure what you mean here - I've never encountered a system that
 kills processes with -9, other than at shutdown time.  Are you sure
 it's -9?

If a process exhausts its resource limits (as set with setrlimit()),
the kernel will typically kill it with SIGKILL. Also, if the available
system-wide memory gets too low, the kernel may start killing of
processes, again with SIGKILL.

When this occurs, the shell from which the process was spawned will
typically write Killed to the terminal.

-- 
Glynn Clements [EMAIL PROTECTED]
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] One-shot? (was: Global variables and stuff)

2004-11-10 Thread Judah Jacobson
What about the following?  It does use unsafePerformIO, but only to
wrap newMVar in this
specific case.

once :: Typeable a = IO a - IO a
once m = let {-# NOINLINE r #-}
 r = unsafePerformIO (newMVar Nothing)
 in do
   y - takeMVar r
   x - case y of
 Nothing - m
 Just x - return x
   putMVar r (Just x)
   return x

The Typeable constraint forces the return value to be monomorphic,
which prevents the
following from happening (the first line doesn't type check under the
constraint):

 let ref = once (newIORef [])
 :t ref
ref :: forall a. IO (IORef [a])
 ref = flip writeIORef foo
 ref = readIORef = (\(x::[Bool]) - print x)
[Illegal instruction

Additionally, I'd like to repeat the point that once (whether
defined my way or Keean's) is
not just a consequence of module initialization; it can actually
replace it in most cases!
For example:

myRef :: IO (IORef Char)
myRef = once (newIORef 'a')

readMyRef :: IO Char
readMyRef = myRef = readIORef

writeMyRef :: Char - IO ()
writeMyRef c = myRef = flip writeIORef c

A library interface might consist of readMyRef and writeMyRef, while hiding 
myRef itself from the user.  However, what happens in IO stays in the 
IO monad; myRef is an action, so the IORef is not initialized until
the first time
that one of read/writeMyRef is called.  Indeed, any action wrapped by once 
will only be run in the context of the IO monad.  IMO, this is the primary 
advantage of a function like once over the proposal for top-level
x - someAction
where the exact time someAction is evaluated is unspecified.  

Are there any applications of module initialization for which once
does not suffice?

-Judah


On Wed, 10 Nov 2004 17:11:31 +, Keean Schupke
[EMAIL PROTECTED] wrote:
 I have written a small library for supporting one-shot without using
 unsfePerformIO...
 The library uses SYSV semaphores under linux to make sure the functional
 argument of
 once is only ever run once. It uses the ProcessID as the key for the
 semaphore, so will
 even enforce the once-only property accross different Haskell threads.
 Some semaphore
 functions are also exported, allowing other constraints to be used (for
 example, once
 only over multiple processes by using a constant ID rather than the
 processID.
 
 I have attached the source for the library incase anyone is interested.
 If people think
 it is useful I could put it up on a website (let me know). Also attached
 is an example,
 which can be compiled with:
 
 ghc -o test NamedSem.hs Test.hs -package posix
 
 Keean.
 
 
 ___
 Haskell-Cafe mailing list
 [EMAIL PROTECTED]
 http://www.haskell.org/mailman/listinfo/haskell-cafe
 
 
 

___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO and State

2004-11-10 Thread Iavor S. Diatchki
Hello,
Concurrency in Haskell (technically GHC) is much like concurrency in 
other languages,
in that you fork off threads and do stuff with them, etc. 
I think you are perhaps thinking of another kind of concurrency, where 
different redexes in
a term are evaluted simultaneously?  Here is an example to illustrate 
what I was talking about
(the point about stToIO making that one law unsafe)

 import Control.Monad.ST
 import Data.STRef
 import Control.Concurrent
 import Control.Monad(when)
 reader :: STRef r Int - ST r ()
 reader r= do x - readSTRef r
  y - readSTRef r
  when (x == y) (reader r)
 writer :: Int - STRef r Int - ST r ()
 writer n r  = do writeSTRef r n
  writer (n+1) r
 main   :: IO ()
 main= do r - stToIO (newSTRef 0)
  forkIO (stToIO (writer 1 r))
  stToIO (reader r)
In GHC the whole program stops when the main thread exits.
So if the law I was talking about holds, this program should
never terminate, as it will forever loop in 'reader'.
However since there is a concurrent thread running that can modify
the state, if 'reader' is interrupted between the two readSTRefs
we will get different values for 'x' and 'y' and 'reader' will stop.
I tried that in GHC and it stops after a little while, so the law does 
not hold.

What is interesting is that I think the law does hold if
we execute an ST computation using runST, so at least in principle
GHC could perform this optimiziation in such situations.
I think the law holds then, as I think no reference can escape to 
concurrent threads,
as if they did their region parameter would become RealWorld, and so 
the computation
could not be runSTed.

-Iavor






Graham Klyne wrote:
At 10:38 08/11/04 -0800, Iavor S. Diatchki wrote:
... Now the above law already doesn't hold when all GHC extensions 
are used,
as when concurrency is present we cannot assume that nobody modified 
the state concurrently.
As a result all pointers in GHC probably behave as if they were 
volatile, which is not very nice.

Eek!  I find this most worrisome.  And I'm not sure that I agree.
I thought that part of the reason for having a monad that it was 
threaded in a useful way through the path of a *single* computation 
(expression evaluation).  If concurrent activities can change that, 
then I sense that they're breaking something quite fundamental in the 
way Haskell should work.

e.g. in a sequence like:
  v :: SomeMonad
  v = do { e1 ; e2 ; e3 }
Then I think that exactly the monad created by e1 is passed to e2, and 
the result of e2 passed to e3, without any visible external 
interference under any circumstance.  Concurrency, as I understand it 
should apply to Haskell, would allow different elements of that 
computation to be performed in different threads/processes, but the 
overall result of the computation should not be changeable.  Put 
another way, the graph reduction model for evaluating a Haskell 
program should not change, just the mechanics actual processes (or 
processors) actually perform the reduction steps.

Or am I really overlooking something here?
#g

Graham Klyne
For email:
http://www.ninebynine.org/#Contact

___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] One-shot? (was: Global variables and stuff)

2004-11-10 Thread Adrian Hey
OK, I'll play again..

On Wednesday 10 Nov 2004 4:39 pm, Judah Jacobson wrote:
 What about the following?  It does use unsafePerformIO, but only to
 wrap newMVar in this
 specific case.

 once :: Typeable a = IO a - IO a
 once m = let {-# NOINLINE r #-}
  r = unsafePerformIO (newMVar Nothing)
  in do
y - takeMVar r
x - case y of
  Nothing - m
  Just x - return x
putMVar r (Just x)
return x


My initial feeling is that this kind of swizzles the problem around a bit
and leaves us right back where we started. Pretty much any use of
unsafePerformIO is unsound, though whether or not this has any bad
consequences probably depends a lot on the context it's used what
transformations and optimisations the compiler implements. But I'd
really like to avoid using it at all if possible. Unless I'm
missing something, once is still unsafe (see below..)

 Additionally, I'd like to repeat the point that once (whether
 defined my way or Keean's) is
 not just a consequence of module initialization; it can actually
 replace it in most cases!

Hmm, must of missed that..

 For example:

 myRef :: IO (IORef Char)
 myRef = once (newIORef 'a')

 readMyRef :: IO Char
 readMyRef = myRef = readIORef

 writeMyRef :: Char - IO ()
 writeMyRef c = myRef = flip writeIORef c

Suppose I had..

myOtherRef :: IO (IORef Char)
myOtherRef = once (newIORef 'a')

There's nothing to stop the compiler doing CSE and producing, in effect..

commonRef :: IO (IORef Char)
commonRef = once (newIORef 'a')

.. followed by substitution of all occurrences of myRef and myOtherRef
with commonRef. I think this would break your programs.

 A library interface might consist of readMyRef and writeMyRef, while hiding
 myRef itself from the user.  However, what happens in IO stays in the
 IO monad; myRef is an action, so the IORef is not initialized until
 the first time
 that one of read/writeMyRef is called.  Indeed, any action wrapped by once
 will only be run in the context of the IO monad.  IMO, this is the primary
 advantage of a function like once over the proposal for top-level
 x - someAction
 where the exact time someAction is evaluated is unspecified.

AFAICS this is only true if the argument to once is something like
(newIORef 'a), in which case the same is also true of the x - newIORef 'a'
solution. Also my own pet solution (SafeIO monad) and Koen's CIO monad
are intended to make it impossible to use constructions whose initial
value depends on when construction occurs.

The intention of the (x - constructor) proposal is more than just
syntactic sugar for (x = unsafePerformIO constructor). I think something
like this really is necessary for a proper solution, though not everybody
agrees what that should be at the moment (and some don't seem agree that
there's a problem in the first place :-)

Hope I haven't missed anything. (I'm sure you'll let me know if you think
I'm being stupid :-)

Regards
--
Adrian Hey

___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] One-shot? (was: Global variables and stuff)

2004-11-10 Thread Keean Schupke
Adrian Hey wrote:
Suppose I had..
myOtherRef :: IO (IORef Char)
myOtherRef = once (newIORef 'a')
There's nothing to stop the compiler doing CSE and producing, in effect..
commonRef :: IO (IORef Char)
commonRef = once (newIORef 'a')
.. followed by substitution of all occurrences of myRef and myOtherRef
with commonRef. I think this would break your programs.
 

Well thats certainly not the case with the solution I posted. There are
no unsafe operations at all (Well the FFI imports are marked 'unsafe'
but that means it is unsafe for them to call back into Haskell)...
The solution I posted uses no unsafePerformIO, and the type of action
allowed is limited to IO (). In other word all results must be returned
as side effects, and the computation either happens (if its the first time)
or doesn't happen...
Also the semaphore method is very flexible, you can run things exactly 
twice,
or you can reset the semaphore and allow the next init to happen (sort of
closing the library and opening it again)... Also once-ness can be 
restricted
accross many domais, thread, process, process-group, multiple sequential
executions, once and for all (may only run once on any machine)... Of course
in this case it ties up one semaphore indefiniely - but hey its a single 
bit, and
there are 65536x32 semaphores available, so its not really going to cause
a problem.

Posix(1b) semaphores with string names would be even better (and have a
slightly neater interface) but linux does not seem to support sem_open, so
I have had to use SYSV semaphores.
   Keean.
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] ANNOUNCE: Haskell Communities Activities Report (7th ed., November 2004)

2004-11-10 Thread Andres Loeh

Right in time, I am pleased to announce -- on behalf of the many
contributers -- that the

  Haskell Communities and Activities Report
  (7th edition, November 2004)

 http://www.haskell.org/communities/

is now available from the Haskell Communities home page in several
formats: PDF, for screenreading as well as printing, HTML, for those 
of you who prefer not to deal with plugins or external viewers, and 
PostScript, for those of you who have nice quick printers that do not 
grok PDF.

Many thanks go to all the people that contributed to this report,
both directly, by sending in descriptions, and indirectly, by doing
all the interesting things that are reported. I hope you will find
it as interesting a read as we did.

If you haven't encountered the Haskell Communities and Activities 
Reports before, you may like to know that the first of these reports
was published in November 2001. Their goal is to improve the 
communication between the increasingly diverse groups, projects and
individuals working on, with, or inspired by Haskell. The idea behind
these reports is simple:

Every six months, a call goes out to all of you enjoying Haskell to
contribute brief summaries of your own area of work. Many of you 
respond (eagerly, unprompted, and well in time for the actual 
deadline ;) ) to the call. The editor collects all the contributions 
into a single report and feeds that back to the community.

When we try for the next update, six months from now, you might want 
to report on your own work, project, research area or group as well.
So, please put the following into your diaries now:


   End of April 2005:
target deadline for contributions to the
  May 2005 edition of the HCA Report


Unfortunately, many Haskellers working on interesting projects are so
busy with their work that they seem to have lost the time to follow
the Haskell related mailing lists and newsgroups, and have trouble even
finding time to report on their work. If you are a member, user or 
friend of a project so burdened, please find someone willing to make 
time to report and ask them to `register' with the editor for a simple 
e-mail reminder in the middle of April (you could point us to them as 
well, and we can then politely ask if they want to contribute, but it 
might work better if you do the initial asking). Of course, they will
still have to find the ten to fifteen minutes to draw up their report,
but maybe we can increase our coverage of all that is going on in the
community.

Feel free to circulate this announcement further in order to
reach people who might otherwise not see it. Enjoy!

Andres Loeh 
[EMAIL PROTECTED]
[EMAIL PROTECTED]


-- 
Haskell Communities and Activities Report (http://haskell.org/communities)

___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] FiniteMap-like module for unordered keys?

2004-11-10 Thread Remi Turk
Ugh, replying to myself...
Obviously, the following contains a few mistakes...:

On Wed, Nov 10, 2004 at 11:34:32AM +0100, R. Turk wrote:
 {-# OPTIONS -fglasgow-exts #-}
 {- I want a Hashable instance for String ;) -}
 import Data.FiniteMap
 import Data.HashTable (hashInt, hashString)
 import Data.Int (Int32)
 
 class Hashable a where hash :: a - Hash
 instance Hashable Int where hash = hashInt
 instance Hashable String where hash = hashString
 
 type Hash = Int32
 newtype HashTable a b = HT (FiniteMap Hash [b])
newtype HashTable a b = HT (FiniteMap Hash [(a,b)])

 
 emptyHT :: HashTable a b
 emptyHT = HT emptyFM
 
 addToHT :: (Hashable a) = HashTable a b - a - b - HashTable a b
 addToHT (HT m) k v
 = HT $ addToFM_C (flip (++)) m (hash k) [v]
addToHT (HT m) k v
= HT $ addToFM_C (flip (++)) m (hash k) [(k,v)]

-- 
Nobody can be exactly like me. Even I have trouble doing it.
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] One-shot? (was: Global variables and stuff)

2004-11-10 Thread Keean Schupke
Hi,
   Here's another completely safe (and simpler way) to limit
a computation to only happen once:
   once' :: IO () - IO ()
   once' f = do
  k - getProcessID
  a - getEnv (showString MyApp.Main $ show k)
  case a of
 Just _ - return ()
 _ - do
f
setEnv (showString MyApp.Main $ show k)  False
Actually both this and the semaphore example show that there is probably
an alternative to allowing top-level '-' type definitions - and that 
would be
to have named-MVars in Haskell. It would be quite easy to code these as a
small C library - and then FFI import the bindings to Haskell. I don't know
whether from a 'purists' point of view whether this represents anything 
better
than module-initialisations - but it does remove the diamond-inheritance 
style
problem you get (if B imports A and C imports A and Main imports B and C,
does A's init get run twice? are there two copies of the variables, each 
initialised
once, or one copy that gets initialised twice?). But either way the idea 
could
be implemented without requiring changes to the language spec or the
compilers, and would just be a library which you could use.

   Keean.
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] FiniteMap-like module for unordered keys?

2004-11-10 Thread John Meacham
On Tue, Nov 09, 2004 at 11:41:49PM +, Jorge Adriano Aires wrote:
 Hello, 
 
  A hash-table becomes rather useless without mutable state AFAICS.
  Without it, one might almost just as well use a list of pairs...
 
 Could you please elaborate? Is there motive why an Hash Table, implemented as 
 FiniteMap of Lists, for instance, wouldn't be worth to using over a simple 
 List? (This wouldn't help G. Klyne of course). I've always wondered why a 
 non-monadic version of is not provided in the GHC libs... 

Sometimes you are willing to pay an arbitrary setup cost for very fast
future lookups. for things like symbols tables for instance. This is
where a constant non-monadic hash would be quite useful, especially since you 
know
it is immutable you can choose things like the number of buckets more
inteligently. or if you wanted to go crazy, generate a perfect-hash on
the fly. Binary trees are good at a lot of things, but their memory
locality is pretty cruddy for lookups or when your key comparason
operator is slow. (I am aware of the absurdity of thinking about memory
locality with a dynamic-dispatch STG-machine, but old habits from my
Kernel programming days die hard :) )
John

-- 
John Meacham - repetae.netjohn 
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe