All the talk of automatic monad lifting has reminded me of an extension I have wanted on several occasions. f x y = z where a = ... b <- ... c <- ... translates too f x y = do let a = .. b <- ... c <- ... z now, this doesn't seem that worth it until you consider guards in which case it becomes _very_ nice compared to the alternative. f x y | b > c = ... | c <= 0 && a > b = ... where a = ... b <- ... c <- ... f x y = ... there is really no clean (IMHO) way to express this idiom otherwise, and the benefits are even greater when you consider pattern guards. Manually you end up with a lot of strange nested cases or spurious subfunctions and generally hard to read and write code. Ideally, it would translate to an 'mdo' rather than a 'do', but not every monad is an instance of MonadFix and although that would be nice to have, it is not really vital since 'mdo', although indispensable sometimes, is not generally needed except in a few special cases so I'd stick to the standard 'do' translation. John -- John Meacham - ⑆repetae.net⑆john⑈
John Meacham wrote:
f x y | b > c = ... | c <= 0 && a > b = ... where a = ... b <- ... c <- ... f x y = ...
there is really no clean (IMHO) way to express this idiom otherwise,
What does this translate to (even if not clean)? I am not sure I understand what this is supposed to do. It looks like the guards depend on things computed inside the monad, so I guess you want the guard code put at the end of the monadic code. But then, by the time you get to the guards, you may have already created side effects in the monad. So running the second version of f after failing the first version is not equivalent to running the second version by itself. Or am I missing something? Thanks, Yitz
On Tue, Sep 20, 2005 at 10:29:14AM +0300, Yitzchak Gale wrote:
John Meacham wrote:
f x y | b > c = ... | c <= 0 && a > b = ... where a = ... b <- ... c <- ... f x y = ...
there is really no clean (IMHO) way to express this idiom otherwise,
What does this translate to (even if not clean)? I am not sure I understand what this is supposed to do.
f x y = do let a = ... b <- ... c <- ... case b > c of True -> ... False -> case c <= 0 && a > b of True -> ... False -> (next fn)
It looks like the guards depend on things computed inside the monad, so I guess you want the guard code put at the end of the monadic code.
yeah. exactly.
But then, by the time you get to the guards, you may have already created side effects in the monad. So running the second version of f after failing the first version is not equivalent to running the second version by itself. Or am I missing something?
this is true. all the actions in a where clause will be executed before pattern matching starts. to limit confusion, we could enforce only a single choice, with pattern guards it is not even that onerous. but I don't know if that is necessary. John -- John Meacham - ⑆repetae.net⑆john⑈
participants (2)
-
John Meacham -
Yitzchak Gale