On 12 May 2011 12:20, Lyndon Maydwell <maydwell@gmail.com> wrote:
Hi Beginners.

I'm trying to implement a program that accumulates a list of items
through many IO actions, then use these in another part of the program
as a list.

I've found Control.Concurrent.Chan which seems to provide a nice
abstraction with getChanContents :: Chan a -> IO [a], but there
doesn't seem to be a way for the source to close the channel.

Are channels the right abstraction for something like this? Should
look in to (itter|enumer)at(or|ee)s instead... They seem to encompass
this model, but look quite involved.

For what it's worth you can implement this abstraction ontop of channels.

module Control.Concurrent.Chan.Closeable where

import           Control.Concurrent.Chan (Chan)
import qualified Control.Concurrent.Chan as C
import           Data.Maybe

getChanWhileJust :: Chan (Maybe a) -> IO [a]
getChanWhileJust ch = fmap (catMaybes . takeWhile isJust) (C.getChanContents ch)

-- λ> chan <- newChan :: IO (Chan (Maybe Integer))
-- λ> writeList2Chan chan (map Just [1..10] ++ [Nothing])
-- λ> getChanWhileJust chan
-- [1,2,3,4,5,6,7,8,9,10]