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 *****************************************