> On Oct 3, 2021, at 5:38 AM, Anthony Clayden <anthony.d.clay...@gmail.com>
> > pattern SmartConstr :: Ord a => () => ...
> Seems to mean:
> * Required constraint is Ord a -- fine, for building
> * Provided constraint is Ord a -- why? for matching/consuming
No. Your signature specified that there are no provided constraints: that's
> I'm using `SmartConstr` with some logic inside it to validate/build a
> well-behaved data structure. But this is an ordinary H98 datatype, not a GADT.
I believe there is no way to have provided constraints in Haskell98. You would
need either GADTs or higher-rank types.
> This feels a lot like one of the things that's wrong with 'stupid theta'
> datatype contexts.
You're onto something here. Required constraints are very much like the stupid
theta datatype contexts. But, unlike the stupid thetas, required constraints
are sometimes useful: they might be needed in order to, say, call a function in
a view pattern.
> checkLT5AndReturn :: (Ord a, Num a) => a -> (Bool, a)
> checkLT5AndReturn x = (x < 5, x)
> pattern LessThan5 :: (Ord a, Num a) => a -> a
> pattern LessThan5 x <- ( checkLT5AndReturn -> (True, x) )
My view pattern requires (Ord a, Num a), and so I must declare these as
required constraints in the pattern synonym type. Because vanilla data
constructors never do computation, any required constraints for data
constructors are always useless.
> For definiteness, the use case is a underlying non-GADT constructor for a BST
> > Node :: Tree a -> a -> Tree a -> Tree a
> > pattern SmartNode :: Ord a => () => Tree a -> a -> Tree a -> Tree a
> with the usual semantics that the left Tree holds elements less than this
> node. Note it's the same `a` with the same `Ord a` 'all the way down' the
Does SmartNode need Ord a to match? Or just to produce a node? It seems that
Ord a is used only for production, not for matching. This suggests that you
want a separate smartNode function (not a pattern synonym) and to have no
constraints on the pattern synonym, which can be unidirectional (that is, work
only as a pattern, not as an expression).
It has been mooted to allow pattern synonyms to have two types: one when used
as a pattern and a different one when used as an expression. That might work
for you here: you want SmartNode to have no constraints as a pattern, but an
Ord a constraint as an expression. At the time, the design with two types was
considered too complicated and abandoned.
Does this help?
Glasgow-haskell-users mailing list