Using monadic boolean value in a guard? (Patternguard)

I just found out about the PatternGuards language extension , which seems really nice.

I am in a situation where I want the template to correspond to a value, apply a monadic Boolean function to this value, and do only something if the result False. Otherwise, I want to perform the default action (it may not be as simple as indicated below).

This can be achieved using ifafter performing pattern matching, but I would prefer not to duplicate the code for the default action or move it to a separate function (i.e. save the drop through the behavior of the guards)

Is there any way to do this without if?

{-# LANGUAGE GeneralizedNewtypeDeriving, PatternGuards #-}

import Control.Applicative
import Control.Monad.State

newtype MyM a = MyM (StateT Int (Either String) a)
                deriving ( MonadState Int
                         , Monad, Applicative, Functor
                         )

--------------------------------------------------------------------------------

foo :: Int -> MyM Bool
foo = undefined

bar :: Either a Int -> MyM Int
bar (Right n)
  | ok <- foo n, ok == False = return 42
bar _ = return 0

Couldn't match expected type โ€˜MyM Boolโ€™ with actual type โ€˜Boolโ€™
In the second argument of โ€˜(==)โ€™, namely โ€˜Falseโ€™
In the expression: ok == False
+4
1

, , . , foo , . ? , . foo RHS, , .

, - , , ,

foo :: Int -> Maybe Bool
...

bar :: Either a Int -> MyM Int
bar (Right n)
  | Just False <- foo n = ...

, .

lambda-case if- .

+3

All Articles