
|No indeed – that's what I meant about the latter being quadratic – it |runs the action far more times than the other. 'quadratic time' usually refers to complexity, not different results, so I thought I'd mention it anyway. |ghci tells me this: |Prelude Control.Applicative Control.Arrow> let iterateM' = let f `op` |x = uncurry (<$>) . ((:) &&& ((x=<<) . f)) in (foldr op (const $ |return []) .) . replicate | |<interactive>:1:92: | Ambiguous type variable `m' in the constraints: | `Monad m' arising from a use of `return' at <interactive>: |1:92-100 | `Functor m' arising from a use of `op' at <interactive>:1:80-81 | Probable fix: add a type signature that fixes these type |variable(s) But surely you have not enabled the monomorphism restriction while avoiding explicit recursion?-) I should, of course, have removed those nasty points - sorry about that, hope noone got hurt - to leave us with: (foldr (flip (((uncurry (<$>).).).((((:)&&&).).((.).(=<<))))) (const $ return []).) . replicate there, much better, isn't it? So obvious and clear that it doesn't even need a name anymore - it is fully declarative and self-explanatory. And it typechecks, so it must be correct!-) And it passes a test, so it isn't wrong, either!-) *Main> ((foldr (flip (((uncurry (<$>).).).((((:)&&&).).((.).(=<<))))) (const $ return []).) . replicate) 3 print () () () () [(),(),()] Sorry, just couldn't resist:-) Now, how do I get that tongue out of my cheek?-) Claus