Closed adnelson closed 9 years ago
There is probably the same as #74. Let's leave this ticket open until this is documented in the code
So I read Michael's article on the subject, and I guess I'm still confused: the implementation of omapM_
still allows for any function of a -> m b
. Only the declaration restricts the type to a -> m ()
. Is this therefore allowing for a compiler optimization of some kind? If that were the case, wouldn't the compiler be able to apply this optimization given an argument that does have type a -> m ()
?
Whether GHC should be able to optimize this away is a nice theoretical discussion to have, to which I don't really have any answers. In practice, it doesn't optimize that away, which is why I made the change. Personally, I think this is the right type signature for the function anyway, and the one in base is too lax, but that's a personal preference.
Fair enough. It's a relatively minor complaint. I'm not sure that it's the "right" signature, but I suppose there's nothing wrong with calling void
on the function you're passing in to mapM_
.
The signature of
mapM_
in the classy-prelude readsBut there shouldn't be any restriction on what the passed-in function returns: it gets ignored anyway. This also introduces a backwards incompatibility with
Prelude.mapM
, which has the signatureLooking into it, the culprit is in
omapM_
.The explicit signature puts an artificial restriction on
omapM_
. The "actual" type isWhich is analogous to the signature of
Prelude.mapM_
.