Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: [Haskell-cafe] Point-free style in guards

6 views
Skip to first unread message

Neil Mitchell

unread,
Jul 22, 2008, 1:27:26 PM7/22/08
to L29Ah, haskel...@haskell.org
Hi

> Why such a style doesn't work, so I must write ugly code like that:
>
> outStanza a | (isMessage a) = outMessage a
> | (isPresence a) = outPresence a
> | (isIQ a) = outIQ a

You can make it slightly prettier, since the brackets are not necessary:

outStanza a | isMessage a = outMessage a
| isPresence a = outPresence a
| isIQ a = outIQ a

Although I suspect that outMessage crashes if isMessage returns False?
And perhaps outMessage is written as outMessage (Message a b) = ...

In which case, I'd write:

outStanza (Message a b) = ...

And then the code no longer looks ugly, uses pattern matching nicely,
requires no "is..." functions and won't crash if things like
outMessage are called incorrectly.

[Note, everything beyond the no need for brackets is a bit of a guess,
just possible ideas to think about]

Thanks

Neil
_______________________________________________
Haskell-Cafe mailing list
Haskel...@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Brandon S. Allbery KF8NH

unread,
Jul 22, 2008, 1:32:34 PM7/22/08
to L29Ah, haskel...@haskell.org

On Jul 22, 2008, at 13:18 , L29Ah wrote:

> outStanza | (isMessage) = outMessage
> | (isPresence) = outPresence
> | (isIQ) = outIQ


>
> Why such a style doesn't work, so I must write ugly code like that:


Because the Haskell 98 Report specifies that guards are rewritten in a
specific way, which in your case produces invalid code. See http://haskell.org/onlinereport/decls.html#pattern-bindings
for details.

--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] all...@kf8nh.com
system administrator [openafs,heimdal,too many hats] all...@ece.cmu.edu
electrical and computer engineering, carnegie mellon university KF8NH


Evan Laforge

unread,
Jul 22, 2008, 1:34:11 PM7/22/08
to Neil Mitchell, haskel...@haskell.org
On Tue, Jul 22, 2008 at 10:27 AM, Neil Mitchell <ndmit...@gmail.com> wrote:
> Hi
>
>> Why such a style doesn't work, so I must write ugly code like that:
>>
>> outStanza a | (isMessage a) = outMessage a
>> | (isPresence a) = outPresence a
>> | (isIQ a) = outIQ a
>
> You can make it slightly prettier, since the brackets are not necessary:
>
> outStanza a | isMessage a = outMessage a
> | isPresence a = outPresence a
> | isIQ a = outIQ a

Also, if it really is in that format, maybe you can write something like:

switch v pairs = maybe (error "no match") ($v) (lookupWith ($v) pairs)

And then you can write the list point-free, though you don't get the
nice guard syntax. I guess lookupWith must be one of my local
functions, but it's easy to write too.

Claus Reinke

unread,
Jul 22, 2008, 2:26:02 PM7/22/08
to haskel...@haskell.org
> outStanza | (isMessage) = outMessage
> | (isPresence) = outPresence
> | (isIQ) = outIQ
>
> Why such a style doesn't work, so I must write ugly code like that:
>
> outStanza a | (isMessage a) = outMessage a
> | (isPresence a) = outPresence a
> | (isIQ a) = outIQ a
>
> so, guards can't be useful in point-free function definitions in any way

You just have to avoid all those pointless language constructs
that let mere Haskellers deal with points, and define your own:

import Control.Monad
import Data.Maybe
import Control.Arrow((&&&))

g |= rhs = uncurry (>>) . ((guard . g) &&& (return . rhs))
a +++ b = uncurry mplus . (a &&& b)
(=|) = (fromJust .)

outStanza = (=|) (((=="m") |= ("message: "++))
+++ ((=="p") |= ("presence: "++))
+++ ((=="i") |= ("iq: "++)) )

Sorry about mentioning those Strings, but then the names shouldn't
really mention the points (Stanza/Message/..), either, right? Or have
I missed the point of this exercise?-)

Claus

Luke Palmer

unread,
Jul 22, 2008, 6:39:40 PM7/22/08
to J.N. Oliveira, haskel...@haskell.org
2008/7/22 J.N. Oliveira <j...@di.uminho.pt>:
> But you still need the extra parentheses...

Not so!

infixl 0 .|
infixl 0 .|... -- 'otherwise' construct
infix 1 .=

(.=) :: (a -> Bool) -> (a -> b) -> (a -> Maybe b)
(.|) :: (a -> Maybe b) -> (a -> Maybe b) -> (a -> Maybe b)
(.|...) :: (a -> Maybe b) -> (a -> b) -> (a -> b)
-- implementations left as exercise for the reader

outStanza = isMessage .= outMessage
.| isPresence .= outPresence
.| isIQ .= outIQ
.|... const 42

Hooray for abusing operators!

Luke

Henning Thielemann

unread,
Jul 31, 2008, 7:37:30 PM7/31/08
to L29Ah, haskel...@haskell.org

On Tue, 22 Jul 2008, L29Ah wrote:

> outStanza | (isMessage) = outMessage
> | (isPresence) = outPresence
> | (isIQ) = outIQ
>
> Why such a style doesn't work, so I must write ugly code like that:
>
> outStanza a | (isMessage a) = outMessage a
> | (isPresence a) = outPresence a
> | (isIQ a) = outIQ a
>
> so, guards can't be useful in point-free function definitions in any way

It's sad that syntactic sugar makes people want even more syntactic sugar
(some people thus call it syntactic heroin).

You can easily achieve the wanted effect by a function like 'select'
http://www.haskell.org/haskellwiki/Case
and that way you can also avoid guards in many cases.

0 new messages