fun with sequence

Go To StackoverFlow.com

2

I have a set of five functions, that could be called one of five ways. I'm expressing that with patern-matching like so,

type Configure = ReaderT Config IO ()
data Step = PreVal
          | PreProc
          | Proc
          | PostProc
          | PostVal

foo :: Step -> Configure
foo PreVal = do some stuff
foo PreProc = do some stuff

and so on bar and baz are set up similarly

I know how to use sequence to call a list of actions. Given a [Step], how could I go about calling [foo,bar,baz]. in sequence, while also calling each possible step.

so it should do this foo PreVal foo PreProc ... and so on bar Preval bar PreProc .. and so on baz ...

2012-04-04 21:56
by Michael Litchard


5

mapM_ (\ f -> mapM_ f [PreVal, PreProc, Proc, PostProc, PostVal]) [foo, bar, baz]
2012-04-04 22:02
by Louis Wasserman


3

I would like to add something to the previous answers. As long as the order of your value constructors is the same as the order of execution of the steps, you could specify deriving (Enum). This would allow you to write the list of all Steps as [PreVal..PostVal] and shorten the code.

Furthermore, consider a case in which you add a step before PreVal or after PostVal. To be sure that your calls consider the newly introduced step, you would better define an instance for Bounded too, and then use minBound and maxBound in the code.

2012-04-04 22:18
by Riccardo T.
Shortens, and removes one more place where changes would have to be made, in the event I add a Step. Thanks for the tip - Michael Litchard 2012-04-04 22:21
@MichaelLitchard: Not really, see my edit : - Riccardo T. 2012-04-04 22:26


2

doThemAll steps = sequence_ $ do
    f <- [foo, bar, baz]
    step <- steps
    return (f step)
2012-04-04 22:13
by Daniel Wagner
Alternatively: sequence_ $ [foo, bar, baz] `ap` steps (or with <*> instead of ap - hammar 2012-04-04 22:20
Ads