[Haskell-cafe] Contravariant applicatives, monads and arrows (was ANN: rematch, an library for composable assertions with human readable failure messages)

Roman Cheplyaka roma at ro-che.info
Tue Apr 16 17:42:38 CEST 2013

My idea was to convert Matcher to be a covariant functor.

It would be essentially a Matcher which has been applied to the tested

And the type argument would denote the result of a computation. For
example, consider

  hasRight :: (Show a, Show b) => Matcher b -> Matcher (Either a b)

Instead it could have type

  hasRight :: F (Either a b) -> F b

... and you then could test 'b' further. F, of course, would handle
errors. But also it could record the chain of functions, so that it
could print it in case of failure, like it Tom's code.

(I guess that means that F has to be a monad. Also it (intentionally)
wouldn't satisfy any usual laws, because we need to record all the
computational steps.)

Or, indeed, you could both preserve the input and add an output, which
would make it a profunctor (and probably a category/arrow).


* Alejandro Serrano Mena <trupill at gmail.com> [2013-04-16 17:12:51+0200]
> Hi,
> First of all, let me say that this work on matchers is really useful :)
> Following Roman advice, I'm trying to find a more principled approach
> that could be useful for this library. It seems that "Match" could
> easily be converted to Either and thus made into Functor, Applicative,
> Alternative and Monad. That would allow to write things like:
> User <$> runMatch (isNot isEmpty) name <*> runMatch (hasItem (is '@')) email
> However, I'm also thinking about the correct way to "combine" matchers
> to get bigger matchers. Basically, if I have matchers on every field
> of a record, can I get a matcher for the entire one?
> My first idea was to make Matcher a functor. However, what I come was
> a contravariant functor: given (a -> b) and Matcher b, I can easily
> construct a Matcher a by running the one in b over this function. So
> we have:
> contramap :: (a -> b) -> Matcher b -> Matcher a
> My first question is: is there any structure similar to applicative
> functors or monads which work on these kind of contravariant functors?
> This also brought into my mind to see Matcher a just as functions a ->
> Match and derive its properties from there. This may give better
> results that the above mentioned idea of looking it as a -> Either
> String a, because in this latter case we have a in covariant and
> contravariant positions and it's difficult to get anything.
> On the other hand, it seems very easy, from a Matcher a and a Matcher
> b, to get a Matcher (a,b). This reminds me a bit about arrows, but
> without output parameters. Does it make sense? I've always been
> reluctant to arrows because I don't fully understand them, but maybe
> this is a good moment to learn.
> Do any of this make sense? I would really like to contribute to this
> great library! :)
> 2013/4/16 Tom Crayford <tcrayford at gmail.com>:
> > Roman,
> >
> > Thanks for the feedback! I'd originally left the QuickCheck and HUnit
> > implementations in this library for convenience, thinking that there aren't
> > going to be many people who care about the transitive dep. But you care, so
> > I'm happy moving them out of core. I'll release a 0.2 with both the HUnit
> > and the QuickCheck runners in separate libraries soonish.
> >
> > Thanks for the haddock tip and the implementation tips.
> >
> > Re the Control namespace, these matchers aren't exclusively a testing tool.
> > I've been using the core api for other purposes as well (primarily for
> > validating forms in user interfaces in conjunction with digestive-functors).
> > I couldn't figure anything better to put it in apart from Control (I
> > definitely don't want it in Test, even though that's going to be what most
> > people use it for). I guess it could be in `Data`, but that doesn't sound
> > much better to me.
> >
> > I'm not amazingly strong at building more principled interfaces right now,
> > so I guess that's something I'll improve on. Are there any concrete
> > suggestions you have there? I'd *like* these to have an `Alternative`
> > instance, but making `Applicative`/`Functor` instances is beyond me right
> > now (I guess I'd have to change the core API for that to work out).
> >
> > Tom
> >
> >
> > ...
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe

More information about the Haskell-Cafe mailing list