
Hello, For a pet project I need a global counter, giving how many times a given function was called. What would you use for that purpose ? Loic

I tend to use Control.Monad.Reader for stateful stuff like this. It is found in the mtl package http://hackage.haskell.org/package/mtl-2.0.1.0 On Wed, Jun 29, 2011 at 7:40 AM, ARJANEN Loïc Jean-David < arjanen.loic@gmail.com> wrote:
Hello,
For a pet project I need a global counter, giving how many times a given function was called. What would you use for that purpose ?
Loic
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
-- Michael Xavier http://www.michaelxavier.net

On 29 June 2011 17:22, Michael Xavier
I tend to use Control.Monad.Reader for stateful stuff like this. It is found in the mtl package http://hackage.haskell.org/package/mtl-2.0.1.0
How would you use reader for a counter?

You can store IORef / MVar / whatever in the environment. The counter is
supposed to be global, so it should work for multiple threads.
Best regards,
Krzysztof Skrzętnicki
On Wed, Jun 29, 2011 at 17:27, Christopher Done
On 29 June 2011 17:22, Michael Xavier
wrote: I tend to use Control.Monad.Reader for stateful stuff like this. It is found in the mtl package http://hackage.haskell.org/package/mtl-2.0.1.0
How would you use reader for a counter?
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

I think my head isn't on straight this morning. I think I meant something
more along the lines of Control.Monad.State
On Wed, Jun 29, 2011 at 8:27 AM, Christopher Done
On 29 June 2011 17:22, Michael Xavier
wrote: I tend to use Control.Monad.Reader for stateful stuff like this. It is found in the mtl package http://hackage.haskell.org/package/mtl-2.0.1.0
How would you use reader for a counter?
-- Michael Xavier http://www.michaelxavier.net

Although it is generally considered an anti-pattern, it is possible to
implement a true mutable, global counter [1] a la
every-other-imperative-language in Haskell.
As some other people have indicated you're better off with the State
monad, but this style comes in handy when you need to translate
imperative code into Haskell without having to do a complete redesign.
-deech
[1] http://stackoverflow.com/questions/6302249/how-to-implement-a-global-counter...
On Wed, Jun 29, 2011 at 10:47 AM, Michael Xavier
I think my head isn't on straight this morning. I think I meant something more along the lines of Control.Monad.State
On Wed, Jun 29, 2011 at 8:27 AM, Christopher Done
wrote: On 29 June 2011 17:22, Michael Xavier
wrote: I tend to use Control.Monad.Reader for stateful stuff like this. It is found in the mtl package http://hackage.haskell.org/package/mtl-2.0.1.0
How would you use reader for a counter?
-- Michael Xavier http://www.michaelxavier.net
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

Christopher Done
I tend to use Control.Monad.Reader for stateful stuff like this. It is found in the mtl package http://hackage.haskell.org/package/mtl-2.0.1.0
How would you use reader for a counter?
Reader is a good choice for an interthread counter: MonadIO m => ReaderT (TVar Int) m I think, then people are talking about global variables in Haskell, what they really want is such a thing. Greets, Ertugrul -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://ertes.de/

On Thu, Jun 30, 2011 at 8:21 AM, Ertugrul Soeylemez
Christopher Done
wrote: I tend to use Control.Monad.Reader for stateful stuff like this. It is found in the mtl package http://hackage.haskell.org/package/mtl-2.0.1.0
How would you use reader for a counter?
Reader is a good choice for an interthread counter:
MonadIO m => ReaderT (TVar Int) m
I think, then people are talking about global variables in Haskell, what they really want is such a thing.
Greets, Ertugrul
Though in this case, you can go with the cheaper IORef, since (presumably) the only operation is going to be incrementing the counter. Just be sure to use atomicModifyIORef[1]. Michael [1] http://hackage.haskell.org/packages/archive/base/4.3.1.0/doc/html/Data-IORef...

Michael Snoyman
Though in this case, you can go with the cheaper IORef, since (presumably) the only operation is going to be incrementing the counter. Just be sure to use atomicModifyIORef[1].
I never recommend (or mention for that matter) IORefs in the beginner list. Also I think than an atomically modified IORef is not necessarily faster. TVars are optimized for that kind of operation. Greets, Ertugrul -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://ertes.de/

On Thu, Jun 30, 2011 at 8:35 AM, Ertugrul Soeylemez
Michael Snoyman
wrote: Though in this case, you can go with the cheaper IORef, since (presumably) the only operation is going to be incrementing the counter. Just be sure to use atomicModifyIORef[1].
I never recommend (or mention for that matter) IORefs in the beginner list. Also I think than an atomically modified IORef is not necessarily faster. TVars are optimized for that kind of operation.
I understand why you avoid mentioning IORef, but I personally find it a simpler solution to the problem, and avoids the need for a beginner to jump into STM. I'd be very interested in seeing if TVars can be as fast as IORefs for this kind of stuff; I know switching the timeout code in Warp to use atomic IORef operations produced a *huge* speed gain, but I may be conflating multiple code changes together. Michael

ARJANEN Loïc Jean-David wrote:
For a pet project I need a global counter, giving how many times a given function was called. What would you use for that purpose ?
Michael Xavier wrote:
I tend to use Control.Monad.State for stateful stuff like this. It is found in the mtl package http://hackage.haskell.org/package/mtl-2.0.1.0
I agree that this is a good approach. If the only state you need is this, it might be easier just to add the counter as an additional parameter to your function, and return its incremented value as part of your return type. For example, you can return a tuple (v, n) where v is the value you were returning before and n is the updated counter. If you also need other kinds of state, or if adding the counter complicates the types throughout your program, then the State monad is the way to go. Regards, Yitz

Yitzchak Gale
I tend to use Control.Monad.State for stateful stuff like this. It is found in the mtl package http://hackage.haskell.org/package/mtl-2.0.1.0
I agree that this is a good approach.
If the only state you need is this, it might be easier just to add the counter as an additional parameter to your function, and return its incremented value as part of your return type. For example, you can return a tuple (v, n) where v is the value you were returning before and n is the updated counter.
If you also need other kinds of state, or if adding the counter complicates the types throughout your program, then the State monad is the way to go.
I agree that this is a good approach for this particular case, if the counter is really attached to the given computation and is not interesting elsewhere. However for state in general there is an approach, which is often forgotten: implicit configurations. This allows you to pull state around without mentioning it explicitly in any way, somewhat related to the ImplicitParams extension, but saner and with a sound theoretical foundation. The advantage is that the state is encapsulated in a type class and thus you can have parallel state threads, invisibly pulling around state attached to certain type constructors. The paper "Functional Pearl: Implicit configurations" by Oleg Kiselyov and Chung-chieh Shan introduces you to this abstraction. Greets -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://ertes.de/
participants (8)
-
aditya siram
-
ARJANEN Loïc Jean-David
-
Christopher Done
-
Ertugrul Soeylemez
-
Krzysztof Skrzętnicki
-
Michael Snoyman
-
Michael Xavier
-
Yitzchak Gale