# [Haskell-cafe] Re: what does @ mean?.....

Achim Schneider barsoap at web.de
Fri Dec 28 11:19:37 EST 2007

```Ben Franksen <ben.franksen at online.de> wrote:

> Achim Schneider wrote:
>
>> ChrisK <haskell at list.mightyreason.com> wrote:
>>
>>> zeroNothing Nothing = Nothing
>>> zeroNothing (Just n) =
>>>   if n == 0 then Nothing else (Just n)
>>>
>>> versus
>>>
>>> zeroNothing Nothing = Nothing
>>> zeroNothing x@(Just n) =
>>>   if n == 0 then Nothing else x
>>>
>> versus
>>
>> zeroNothing Nothing = Nothing
>> zeroNothing x =
>>     let (Just n) = x
>>     in if n == 0 then Nothing else x
>>
>> so, @ is kind of like a let, just with its arguments flipped.
>
> However, if  x@(Just n)  fails to match, the next clause is chosen,
> whereas the variable pattern  x  matches always. Thus, the last
> version works only because the other possible case (Nothing) has
> already been handled. IOW, in the second version of zeroNothing you
> may swap the order of patterns, but not in the third one.
>
Actually, I considered working it out to

nothingIf :: (a -> Bool) -> Maybe a -> Maybe a
nothingIf f m = m >>= (\j -> if f j then Nothing else Just j)

nothingIf' :: (a -> Bool) -> Maybe a -> Maybe a
nothingIf' f m = m >>= (\j -> if f j then Nothing else m)

zeroNothing = nothingIf (== 0)
zeroNothing' = nothingIf' (== 0)

, but was too lazy. Hopefully only because it completely messes up my
point.

OTOH,

zeroIf :: MonadPlus m => (a -> Bool) -> m a -> m a
zeroIf f m = m >>= (\nz -> if f nz then mzero else m)

zeroZero :: (MonadPlus m, Num a) => m a -> m a
zeroZero = zeroIf (==0)

makes it interesting again as you can't construct a Just value with it.

```