> On Oct 3, 2021, at 5:38 AM, Anthony Clayden <anthony.d.clay...@gmail.com> 
> wrote:
> >    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 
your ().

> 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.

For example:

> 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 
> Tree.

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

Reply via email to