Ticket #2399 (closed feature request: fixed)

Opened 5 years ago

Last modified 3 years ago

Template Haskell: support for view patterns

Reported by: fons Owned by: igloo
Priority: low Milestone: _|_
Component: Template Haskell Version: 6.11
Keywords: Cc: rwbarton@…, audreyt@…, duncan2nd@…, reiner.pope@…, id@…, vogt.adam@…
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Difficulty: Unknown
Test Case: Blocked By:
Blocking: Related Tickets:

Description

TH's Pat type doesn't include a constructor for view patterns, which would ceratinly be useful.

As an example, Reid Barton suggested using view patterns for creating a regular expression quasiquoter (rx) [1].

For example, to check if a string matches certain regular expresion:

example x = case x of
 [$rx|.*foo.*] -> "contains foo"
 _             -> "doesn't contain foo"

Using pattern views, the quasiquoter would expand to

example x = case x of
 ((=~".*foo.*")->True) -> "contains foo"
 _             -> "doesn't contain foo"

[1]  http://www.haskell.org/pipermail/template-haskell/2008-June/thread.html#669

Attachments

viewpatterns-ghc.dpatch Download (161.7 KB) - added by reinerp 3 years ago.
viewpatterns-th.dpatch Download (3.9 KB) - added by reinerp 3 years ago.
viewpatterns-test.dpatch Download (89.6 KB) - added by reinerp 3 years ago.

Change History

Changed 5 years ago by rwbarton

  • cc rwbarton@… added

Changed 5 years ago by simonpj

  • priority changed from normal to low
  • difficulty set to Unknown
  • milestone set to _|_

Yes, there are many ways in which Template Haskell lags the various GHC extensions, and view patterns are only one of them. Furthermore, view patterns are a rather new and experimental feature, so it seems premature to "bless" them in TH.

In any case, it's probably fairly easy to add a guard instead, since you are generating the program with a TH program.

Simon

Changed 5 years ago by AudreyTang

Simon, it's difficult to add a guard there, because a QuasiQuoter? accepts the pattern-generation function of the form:

quoteExprPat :: String -> TH.PatQ

But in TH, Guard is part of Body, so a quasiquoter designated to the PatQ side cannot affect the BodyQ side.

As there seems to be no other Pat constructors that's useful for a [$rx|...|] at the pattern side, would you consider accepting a patch that adds ViewP for 6.10?

Cheers,

Audrey

(The context for [$rx|...|] is  http://hackage.haskell.org/cgi-bin/hackage-scripts/package/regexqq btw.)

Changed 5 years ago by AudreyTang

  • cc audreyt@… added

Changed 5 years ago by simonpj

Ah I see. I'd missed the quasiquoter connnection.

One way to fix this would be to add view patterns to TH. But it made me wonder: why aren't pattern guards compositional? At the moment they are resolutely top-level. And, as you say, not part of patterns. But syntax aside it would make perfect sense to make them part of a pattern:

  pat ::= var |  C pat1 ... patn
       |  pat|quals

where qual is a pattern-guard "qualifier". So (again, syntax aside) you could write

  f (x | x>3) = ...

  g ([y] | Just z <- lookup y) = ...

That would push pattern guards into the syntax of patterns. Now view patterns are syntactic sugar:

  (exp -> pat)   means   (x | pat <- exp x)
  where x is fresh

The reverse encoding is also possible

  (pat | quals)  means   (f -> Just (v1,...,vn))
where
  (v1,...,vn) are the variables bound by pat
  f pat | quals = Just vs

I'm not sure I'm advocating this (yet!), but I hadn't thought of it before so I thought I'd jot it down.

If TH users agree about just how to beef up patterns, I'm not against adding it. I'm just a bit conscious that view patterns are experimental and the more concrete we pour the harder it becomes to change.

Simon

Changed 5 years ago by simonmar

  • architecture changed from Unknown to Unknown/Multiple

Changed 5 years ago by simonmar

  • os changed from Unknown to Unknown/Multiple

Changed 5 years ago by duncan2nd

  • cc duncan2nd@… added

Changed 4 years ago by reinerp

  • cc reiner.pope@… added

Changed 4 years ago by guest

  • cc id@… added

Changed 4 years ago by porges

  • version changed from 6.9 to 6.11

I came across this limitation also, while trying to write something to emulate Erlang's BitSyntax?.

Erlang allows you to write:

<<H:2,T:6>> = <<"A">>

And then H and T are both bound to 1. Similarly:

<<01000001>> == <<"A">>

is true.

I was hoping to be able to write a quasiquoter to do something like this:

highBitSet
Word8 → Bool highBitSet [$bits| H:1, _:7 |] = H

But this currently is not possible (AFAIK!). So, basically I'd like to put a vote in for this.

Would this be a hard change to make?

Changed 4 years ago by simonpj

What is the "change" that you advocate? The one that this ticket started with, namely adding view patterns to TH?

I have not looked into it in detail, but I don't think it's hard. As usual for TH, it means

  • Design the TH syntax data types
  • Write code in GHC to convert between TH and HsSyn?

No rocket science. The trouble is that these TH extensions never get to the top of my priority list! But nagging is good... that ups the priority. I also always hope that someone else will to the work and send a patch!

Simon

Changed 3 years ago by aavogt

  • cc vogt.adam@… added
  • failure set to None/Unknown

Improved Pat could address #3919

Changed 3 years ago by reinerp

Changed 3 years ago by reinerp

Changed 3 years ago by reinerp

Changed 3 years ago by reinerp

  • owner set to igloo

I've attached patches (to ghc, template-haskell, and the testsuite) which implement and test the request. The Pat datatype in template-haskell now has a constructor ViewP Exp Pat, which is recognised when splicing. Also, GHC no longer complains about "exotic patterns" when writing things like [p|(id -> x)|].

My thought about view patterns versus Simon's "compositional pattern guards": view patterns are simpler. In particular, an important motivation seems to be for pattern quasiquoters. The main feature such quasiquoters require is being able to do computation before performing the pattern match, and the ViewP constructor expresses exactly that, and no more.

In my patch, I have left the ViewP case of Language.Haskell.TH.Lib.rename as a fail. To implement this case would seem to require extending rename to expressions as well as just patterns; and in any case, I am not sure of the purpose of this function.

Changed 3 years ago by reinerp

  • status changed from new to patch

Changed 3 years ago by simonpj

  • status changed from patch to merge

Thank you Reiner. I've applied the patches. I agree with your comment about rename; indeed I propose to nuke it altogether #4423.

Patches are:

-- GHC
Sun Oct 10 14:17:20 BST 2010  Reiner Pope <reiner.pope@gmail.com>
  * Template Haskell: add view patterns (Trac #2399)

-- template haskell library
Sun Oct 10 13:39:05 BST 2010  Reiner Pope <reiner.pope@gmail.com
  * Added view patterns (Trac #2399)

-- testsuite
Sun Oct 10 13:09:43 BST 2010  Reiner Pope <reiner.pope@gmail.com>
  * Add tests for view patterns in template haskell (Trac #2399)

I'd quite like to push this into 7.0 if we still have time. It's an API change so we can't do it in a patch release.

Simon

Changed 3 years ago by igloo

  • status changed from merge to closed
  • resolution set to fixed

All 3 merged.

Note: See TracTickets for help on using tickets.