[Haskell] Views in Haskell

David Roundy droundy at darcs.net
Mon Jan 22 15:13:35 EST 2007

On Mon, Jan 22, 2007 at 02:57:27PM +0000, Simon Peyton-Jones wrote:
> Dear Haskellers
> Provoked by a discussion with Don Syme, and after some helpful
> conversations at POPL, I have finally written up a proposal for adding
> "view patterns" to Haskell.  We've wanted views for a long time, but they
> have never made it, into GHC at any rate.  This proposal is a very
> lightweight (and hence, I hope, cost-effective) proposal for a view-like
> mechanism.
>         http://hackage.haskell.org/trac/haskell-prime/wiki/ViewPatterns
> I'm thinking of implementing it in GHC, so I'd be interested in feedback of the form
>         - how desirable is it to have a feature of this general form?
>         - can this particular proposal be improved?

It looks pretty cool to me, and simple enough to be reasonable.

One feature that would be particularly interesting would be to add some
sort of annotation mechanism to describe a possible "complete" set of views
(with respect to improving warnings about inexhaustive pattern matching).
I wonder if you could have something like:

data Foo = FooBar Bar | FooBaz Baz

foobar :: Foo -> Maybe Bar
foobaz :: Foo -> Maybe Baz

{-# COMPREHENSIVE_VIEWS Foo : foobar, foobaz #-}

which tells the compiler that for any Foo, one of foobar and foobaz will
return a non-Nothing result.  It'd allow us--at least in the simple views
case--to retain the existing level of warnings, and ought also to be useful
in somewhat trickier case as well.

Another idea is whether the syntax could be extended to indicate a failure
to match? This would actually be useful even without views, but it's
particularly useful with views (and especially so in the context of the
above warnings).  I'd imagine something like (with stupidly chosen syntax
of !!!)

foo (_:_) = True
foo _ = False

foo' !!![] = True
foo' _ = False

Here I've defined two identical functions to describe what I mean by "!!!".
I didn't gain anything in this case, but might gain some clarity if there
are multiple constructors.  But more to the point, if we're using views (of
the vanilla Maybe-always variety), we could gain some efficiency this way.

foo ([], view -> a, []) = foo1 a
foo (x, !!! view ->, []) = foo2 x
foo (_, view -> a, y) = foo3 a y

This isn't a very good example, but the point is I'd like to be able to
match on Nothing and get the same benefits you mention about the compiler
being assumed to optimize by calling view only once.  We could achieve this
by reordering the patterns, but I believe (although I failed to come up
with one above) that there are sets of pattern matches that aren't
reducible in that way, which it'd be nice to be able to express succinctly
by matching on failure to match a pattern.

Maybe this should be

foo (x, view /->, []) = foo2 x

or something like that, to indicate failure, that view doesn't match?
David Roundy
Department of Physics
Oregon State University
Haskell mailing list
Haskell at haskell.org

More information about the Haskell-prime mailing list