I\'ve been trying to figure this out for a couple of hours now. I need to calculate how many recursive calls happened using a certain function:
maximum\' ::
-
This is a digression on Michail's and user2297560's answers.
What if, instead of rewriting the function from scratch to add tracking functionality, we could reuse the original implementation and "instrument" it in some way?
We could write a base function that
- Is monadic, but polymorphic on the monad.
- Is defined using anonymous recursion, with the help of
fix
.
For example:
import Data.Function(fix)
import Data.Functor.Identity
maximumAux :: (Monad m,Ord a)
=> ([a] -> m a)
-> [a] -> m a
maximumAux _ [] = error "maximum of empty list"
maximumAux _ [x] = return x
maximumAux recurse (x:xs) =
do maxTail <- recurse xs
return (max x maxTail)
maximumPure :: Ord a => [a] -> a
maximumPure as = runIdentity (fix maximumAux as)
And then instrument it like this, reusing the original logic:
maximumInstrumented :: (Ord a, Show a) => [a] -> IO a
maximumInstrumented = fix (instrument maximumAux)
where
instrument auxf iorecurse as =
do print $ "starting call with params " ++ show as
a <- auxf iorecurse as
print $ "ending call with value" ++ show a
return a
But perhaps defining functions as "monadic by default" isn't too practical.
- 热议问题