Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pattern matching with Alternative empty or Applicative pure

I know it is possible, to pattern match against (named) constructors like so:

f1 :: Maybe a -> Bool
f1 Nothing = False
f1 (Just x) = True -- in reality have something that uses x here

f2 :: [a] -> Int
f2 [] = False
f2 x = True

How can I write such a function for general Alternatives similar to

f :: (Alternative m) => m a -> Bool
f empty = False
f x = True

If I try this, I get the error Parse error in pattern: empty. Which makes sense, I guess, as empty as a function here and not a constructor. But how can I accomplish this for general Alternatives idiomatically?

Edit 1: My actual goal is to define a Monad instance (and probably also a MonadPlus instance) for a custom result type. Instead of the basic Either Error Result type, it should support a Maybe Error (and if possible also other Alternatives like [Error]) as error type and also some Applicative as result type in order to support lazy evaluation, for example with the result type (Maybe Error, [Tokens]) of a tokenizer.

I'd like something similar to

instance (Alterantive mErr, Applicative mRes) => Monad (mErr e, mRes a) where
  return x = (empty, pure x)
  (empty, pure x) >>= f = f x
  (err, x) >>= f = (err, x)
like image 702
Uroc327 Avatar asked Jan 26 '23 07:01

Uroc327


1 Answers

The best you can do is:

f :: (Eq (m a), Alternative m) => m a -> Bool
f x | x == empty = False
    | otherwise = True
like image 106
mithrandi Avatar answered Mar 04 '23 23:03

mithrandi