There's an extension to GHC: 'Postfix Operators' .
https://downloads.haskell.org/~ghc/8.6.1/docs/html/users_guide/glasgow_exts…
Turns out Hugs can do that too (in Hugs mode).
> (!) :: Num a => a -> a -- note defined as monadic
> (!) 0 = 1 -- lhs of equation must use prefix form
> (!) n = n * ((n - 1) !) -- but rhs can use postfix
So (3 !) returns 6, etc. The parens are needed so that it's parsed as a
section.
I also took a leaf out of Oleg's book and built a variadic postfix operator
http://okmij.org/ftp/Haskell/polyvariadic.html
That is, (3 ~- 7) is parsed as 'subtract 3 from 7'. (3 ~-) is parsed as
postfix negate 3 aka 'subtract 3 from zero'. It kinda worked, but the terms
need a lot of explicit signatures and/or tricky type casting.
AntC
Thank you for the encouraging words to my previous thread. I can report
Hugs is indeed easy to hack.
Getting to build from source was only mildly painful. (Mostly due to my
total ignorance of Unix.)
After being so used to Functional thinking, it is a wrench going back to
programming in procedural code (C/C++) with side-effects and global
variables. But I'm only tweaking the logic, not building anything from the
ground up. (I've not before programmed in earnest in C, but it seems close
enough to BCPL from my varsity days.)
Chiefly, as I suspected, Hugs has a very firm foundation to start from.
There's a deal of static type/class/instance analysis built up from the
program text, which means I can easily detect the conditions under which I
want to relax some of Hugs well-principled rules. (I'm implementing
well-principled but more subtle rules.)
So I have a modified version of the FD consistency rules, that supports
expressing a type-level type equality test, but avoids the bogusness in GHC
Trac #10675. With the equality test I can now express all the examples in
the HList paper [2004] -- those guys abandoned Hugs.
I have a better version of the instance overlap rules, determined
statically from examining instance heads. IMO GHC's deferred checking is
far too shonky: you think your instances are OK then many moons later you
(or more likely somebody using your library) gets puzzling rejections to do
with overlaps.
A quick q in case anybody's listening: Hugs used to have something called
'Multi-instance' overlap resolution. There's references to it in the code
and older documentation. But it's broken and was withdrawn. Anybody know
what it was trying to do or where I can find docos? It seems it was trying
to defer checking much like GHC, in which case I won't pursue it.
I'm now working through an approach for my 'Instance Apartness Guards'
proposal
https://github.com/AntC2/ghc-proposals/blob/instance-apartness-guards/propo…
I can express all the examples there, including the very awkward Andy A-M
one (using classes/instances with FunDeps rather than type families). But
it needs inserting extra instances and lots of instance constraints for
type improvement.
So my next hack is to change the rules for overlap resolution where there's
also FunDep(s). Again this can all be done at static analysis time: Hugs
determines the sequence to try instances as it processes/validates each
instance.
It is a joy to work in a version of Haskell that has what I want; and not a
load of cruft I don't want, but which causes continual obfuscation. Thank
you again to the Hugs team.
AntC
It's always seemed to me that field labels in records are more
constructor-like than term-like. And pattern-matching on them is more like
using them as (de-)constructors.
But H98 records create a selector function named for the field; and because
it's a function it must be term-like.
TRex field labels don't suffer this restriction: you don't get a selector
function; if you want a select by label from a TRex row, use the `#label
row` syntax.
Then I wondered: TRex labels appear only in a handful of syntax
productions. How hard would it be to allow them to look like constructors?
The answer is it's dead easy; you need only to change the syntax (in yacc
plus a tweak to the lexer); you don't need to change any of the code for
building/matching/typing rows. For now, I'm allowing labels to start either
upper or lower case.
Some example code here
https://github.com/ghc-proposals/ghc-proposals/pull/160#issuecomment-420272…
In particular, there's an example defining a Lens `bar` over any Trex row
containing a label `Bar`. (The main purpose of that definition is to
demonstrate every syntactic construct in which TRex allows labels, so it
could be terser.) Note that unlike Lenses over H98 style records, this
doesn't need an overloading for each different datatype containing a label
of some name.
My jazzy name for such Lense is 'OpTRex', as imagined here
https://github.com/ghc-proposals/ghc-proposals/pull/158#issuecomment-414060…
AntC