Send Beginners mailing list submissions to
        [email protected]

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
        [email protected]

You can reach the person managing the list at
        [email protected]

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 <[email protected]>
Subject: [Haskell-beginners] Random animals
To: [email protected]
Message-ID: <[email protected]>
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? <[email protected]>
Subject: Re: [Haskell-beginners] Re: Simple Haskell daemon
To: Amy de Buitl?ir <[email protected]>
Cc: [email protected]
Message-ID:
        <[email protected]>
Content-Type: text/plain; charset=UTF-8

On Tue, Nov 16, 2010 at 10:11 PM, Amy de Buitléir <[email protected]> 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 <[email protected]>
Subject: [Haskell-beginners] Re: Simple Haskell daemon
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=utf-8

Thank you very much for those suggestions, Chaddaï.



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

_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners


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

Reply via email to