[Haskell-beginners] Re: pattern for tree traversel with a state
Andreas-Christoph Bernstein
andreas.bernstein at medien.uni-weimar.de
Sat Oct 25 13:35:32 EDT 2008
Brent Yorgey wrote:
> On Thu, Oct 23, 2008 at 11:47:43PM +0100, Jan Jakubuv wrote:
>
>> 2008/10/23 Andreas-Christoph Bernstein <andreas.bernstein at medien.uni-weimar.de>:
>>
>>> apfelmus wrote:
>>>
>>> But what i need is
>>> [(0,"a"),(1,"a"),(2,"a"),(1,"a"),(0,"a")]
>>>
>>> So state changes should affect only their subtree, not the rest of the tree
>>> to the right.
>>>
>>>
>> It seems to me that you are looking for the Reader monad. Try the following:
>>
>> import Control.Monad.Reader
>>
>> t :: (a -> b -> b) -> BTree a -> Reader b (BTree b)
>> t f (Leaf x) = do
>> s <- ask
>> return (Leaf (f x s))
>> t f (Fork x l r) = do
>> s <- ask
>> l' <- local (f x) (t f l)
>> r' <- local (f x) (t f r)
>> return (Fork (f x s) l' r')
>>
>> new = runReader (t modState sampleTree) globalState
>>
>> Then,
>>
>> flattenTree new
>>
>> gives you
>>
>> [(0,"a"),(1,"a"),(2,"a"),(1,"a"),(0,"a")]
>>
>> I think that the Reader monad is a standard way to this. When you want
>> the state to affect also the rest of the tree then use the State
>> monad.
>>
>
> Just to elaborate on Jan's code, the Reader monad represents an
> *immutable* state---that is, a read-only "environment" that gets
> threaded through your computation which you can access at any time
> (using "ask"). However, using the "local" function, you can run
> subcomputations within a different environment, obtained by applying
> some function to the current environment. So this does exactly what
> you want---after the subcomputation is finished, its locally defined
> environment goes out of scope and you are back to the original
> environment. Using the Reader monad in this way is a common idiom for
> representing recursive algorithms with state that can change on the
> way down the call stack, but "unwinds" as you come back up, so
> recursive calls can only affect recursive calls below them, not ones
> that come afterwards.
>
> -Brent
>
That is what i was looking for. Thank you all very much for your help.
Kind regards,
Andreas
More information about the Beginners
mailing list