[Haskell-cafe] Pattern guards seen in the wild?
Viktor Dukhovni
ietf-dane at dukhovni.org
Fri Oct 1 05:29:16 UTC 2021
On Fri, Oct 01, 2021 at 04:06:45PM +1300, Anthony Clayden wrote:
> Browsing some docos for a completely other purpose, I came across this code:
>
> > f' [x, y] | True <- x, True <- y = True
> > f' _ = False
>
> (In User Guide 6.7.4.5 Matching of Pattern Synonyms.)
A fairly synthetic exmaple...
> In 10 years of reading Haskell code, I've never seen them. Does anybody use
> them? Are they more ergonomic than guards as plain Boolean expressions? Are
> 'local bindings' any different vs shunting the `let` to the rhs of the `=`?
The pattern guards in the example are far from compelling as written,
but I do regularly use them in I hope more natural contexts.
> I'd write that code as:
>
> > f'' [x at True, y at True] = True
> > f'' _ = False
Or with no guards at all:
f'' [x, y] = x && y
f'' _ = False
More realistic examples:
https://github.com/kazu-yamamoto/dns/blob/master/internal/Network/DNS/Decode/Parsers.hs#L46-L49
Or code to process a possibly not yet complete (to be continued) SMTP
greeting:
smtpGreeting :: Int -> SmtpReply -> SmtpM B.ByteString
smtpGreeting _ r
| replyCont r = pure B.empty
| code <- replyCode r
, code `div` 100 /= 2 = B.empty <$ modify' bail code
| otherwise = smtpSendHello
where
bail code s =
s { smtpErr = ProtoErr code $ replyText r }
which would otherwise be something like:
smtpGreeting :: Int -> SmtpReply -> SmtpM B.ByteString
smtpGreeting _ r =
if replyCont r
then pure B.empty
else let code = replyCode r
in if code `div` 100 == 2
then smtpSendHello
else B.empty <$ modify' bail code
where
bail code s =
s { smtpErr = ProtoErr code $ replyText r }
but I find the pattern guard form to read "declarative", with less "if
then else" baggage and nesting getting in the way of seeing the
essential conditions.
--
Viktor.
More information about the Haskell-Cafe
mailing list