3

I'm running a number of times now into a similar pattern which is error-prone (typos can skip some caching) and simply doesn't look nice to me. Is there a better way of writing something like this?

sum_with_cache' result cache ((p1,p2,p3,p4):partitions) = let (cache_p1, sol1) = count_noncrossing' cache p1 (cache_p2, sol2) = count_noncrossing' cache_p1 p2 (cache_p3, sol3) = count_noncrossing' cache_p2 p3 (cache_p4, sol4) = count_noncrossing' cache_p3 p4 in sum_with_cache' (result+(sol1*sol2*sol3*sol4)) cache_p4 partitions 

So basically N operations which can update the cache?

I could write also something like:

process_with_cache' res cache _ [] = (cache, res) process_with_cache' res cache f (x:xs) = let (new_cache, r) = f cache x in process_with_cache' (r:res) new_cache f xs process_with_cache = process_with_cache' [] 

But that doesn't look really clean either. Is there a nicer way of writing this code?

2
  • 1
    If you want to maintain an implicit state between function calls, look at Control.Monad.State. Commented Mar 17, 2013 at 2:13
  • Are you trying to build a memo table? haskell.org/haskellwiki/Memoization Commented Mar 17, 2013 at 11:29

1 Answer 1

8

Another similar pattern is when you request a series of named random numbers:

let (x, rng') = random rng'' (y, rng) = random rng' in (x^2 + y^2, rng) 

This is exactly when using a state monad is the right way to go:

import Control.Monad.State 

For all random number generators of type (RandomGen g) => g there is a state monad State g, which threads the state implicitly:

do x <- state random y <- state random return (x^2 + y^2) 

The state function simply takes a function of type s -> (a, s) and turns it into a computation of type State s a, in this case:

state :: (RandomGen g) => (g -> (a, g)) -> State g a 

You can run a State computation by using runState, evalState or execState:

runState (liftA2 (\x y -> x^2 + y^2) (state random) (state random)) (mkStdGen 0) 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.