Send Beginners mailing list submissions to
        beginners@haskell.org

To subscribe or unsubscribe via the World Wide Web, visit
        http://www.haskell.org/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
        beginners-requ...@haskell.org

You can reach the person managing the list at
        beginners-ow...@haskell.org

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."


Today's Topics:

   1.  Random animals (Amy de Buitl?ir)
   2. Re:  Re: Simple Haskell daemon (Chadda? Fouch?)
   3.  Re: Simple Haskell daemon (Amy de Buitl?ir)


----------------------------------------------------------------------

Message: 1
Date: Wed, 17 Nov 2010 00:13:08 +0000 (UTC)
From: Amy de Buitl?ir <a...@nualeargais.ie>
Subject: [Haskell-beginners] Random animals
To: beginners@haskell.org
Message-ID: <loom.20101117t005428-...@post.gmane.org>
Content-Type: text/plain; charset=us-ascii

I have this function:

-- | Choose an element at random from a list and return the element and its 
index
-- Ex: runState (randomListSelection ['a', 'b', 'c', 'd', 'e']) (mkStdGen 1)
randomListSelection :: (RandomGen s) => [a] -> State s (Int, a)
randomListSelection xs = do
  i <- State $ randomR (0,length xs - 1)
  return (i, xs !! i)

I want to repeatedly select random elements from a list. I know the code below 
is
totally wrong, but it's the closest I've gotten so far. When I run it in ghci, I
get the SAME random element each time, until I reload the module. I guess that's
because g is always the same. I'm still struggling with monads, and would
appreciate any advice on how to fix this.

chooseCreatur = do
  g <- getStdGen
  return (evalState (randomListSelection ["cat", "dog", "lion", "mouse"]) g)

FWIW, I'll be calling it from a loop within the IO monad. The real list will be
growing and shrinking in size.



------------------------------

Message: 2
Date: Wed, 17 Nov 2010 09:16:48 +0100
From: Chadda? Fouch? <chaddai.fou...@gmail.com>
Subject: Re: [Haskell-beginners] Re: Simple Haskell daemon
To: Amy de Buitl?ir <a...@nualeargais.ie>
Cc: beginners@haskell.org
Message-ID:
        <aanlktikoam0tl==doe450wuyunbfpoxhvd3n+4abk...@mail.gmail.com>
Content-Type: text/plain; charset=UTF-8

On Tue, Nov 16, 2010 at 10:11 PM, Amy de Buitléir <a...@nualeargais.ie> wrote:
> Patrick LeBoutillier <patrick.leboutillier <at> gmail.com> writes:
>
>>
>> Amy,
>>
>> Here's a small suggestion:
>>
>> If the start and loop functions always returns Nothing, I think it may
>> be cleaner to
>> simply make them return ().
>
> Thank you Patrick, that make the interface easier for the user to understand.
>
> The "loop" function does return something when it is called recursively, but 
> the
> outer call never returns anything, so my first try was to have two separate
> functions.

Even recursively it doesn't return anything, or rather it always ends
up returning Nothing since that's what the base case returns and the
recursive case don't modify it, also finalise already returns (), so
you can write :

> loop :: (a -> IO a) -> (a -> IO ()) -> a -> IO ()
> loop work finalise d = do
>  timeToStop <- readMVar termReceived
>  if timeToStop
>    then finalise d
>    else work d >>= loop work finalise

To avoid the need to repeat the same parameters at each call of the
recursive function, you can use a "worker-wrapper" (? not sure of the
term) transformation :

> loop :: (a -> IO a) -> (a -> IO ()) -> a -> IO ()
> loop work finalise d = loop' d
>   where
>     loop' d = do
>       timeToStop <- readMVar termReceived
>       if timeToStop
>         then finalise d
>         else work d >>= loop'

Which finally can be directly included in your start function :

> start
>  -- | This function will be invoked when the daemon starts.
>  :: IO a
>  -- | This function will be invoked in the main loop.
>  -> (a -> IO a)
>  -- | This function will be invoked when the daemon shuts down.
>  -> (a -> IO ())
>  -- | Returns nothing.
>  -> IO ()
> start initialise work finalise =
>    installHandler sigTERM (Catch handleTERM) Nothing
>        >> initialise
>        >>= loop
>   where
>     loop d = do
>       timeToStop <- readMVar termReceived
>       if timeToStop
>         then finalise d
>         else work d >>= loop

Defining functions at the top level instead may be clearer or more
useful in certain cases, but I'm not sure this is one of those cases
(you don't want to export loop, start and loop bodies are very short,
and you can simplify and optimize loop body by making it a local
function).
-- 
Jedaï


------------------------------

Message: 3
Date: Wed, 17 Nov 2010 10:30:54 +0000 (UTC)
From: Amy de Buitl?ir <a...@nualeargais.ie>
Subject: [Haskell-beginners] Re: Simple Haskell daemon
To: beginners@haskell.org
Message-ID: <loom.20101117t113004...@post.gmane.org>
Content-Type: text/plain; charset=utf-8

Thank you very much for those suggestions, Chaddaï.



------------------------------

_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://www.haskell.org/mailman/listinfo/beginners


End of Beginners Digest, Vol 29, Issue 24
*****************************************

Reply via email to