Pattern matching and GADTs
Gabor Greif
ggreif at gmail.com
Mon Mar 9 11:09:24 UTC 2015
On 3/3/15, Simon Peyton Jones <simonpj at microsoft.com> wrote:
>
> | data Bar a where
> | Listy :: Bar [Int]
> |
> | {-
> | foo :: a -> Bar a -> Int
> | foo [0] Listy = 1
>
> Well you'd get a seg-fault from the call (foo True (undefined :: Bar
> [Int])). So we really MUST match the (Bar a) arg before the 'a' arg. And
Oh, okay, I see! But you surely mean
(foo True (undefined :: Bar Bool))
> Haskell only offers one way to do that, which is to put it first.
>
> You don't have to change the argument order. Write
>
> foo xs Listy | [0] <- xs = 1
Yeah, this is what I gave as foo'' in my examples. What about making
an irrefutable pattern match?
{{{
foo :: a -> Bar a -> Int
foo ~[a] Listy = a
}}}
While I guess this won't SEGV, it may error with a pattern match
failure. Besides, the type-checker won't let us:
Couldn't match expected type `a' with actual type `[a0]'
`a' is a rigid type variable bound by
the type signature for: foo :: a -> Bar a -> Int
So the pattern guard solution looks like our best option to fix the
ordering issue.
Thanks,
Gabor
>
> Simon
>
> | -----Original Message-----
> | From: ghc-devs [mailto:ghc-devs-bounces at haskell.org] On Behalf Of Gabor
> | Greif
> | Sent: 03 March 2015 14:13
> | To: ghc-devs at haskell.org
> | Subject: Re: Pattern matching and GADTs
> |
> | This might be off-topic for your paper, but possibly relevant for GADT-
> | based programming:
> |
> | In the below snippet
> | -----------------------------------------------------------------
> | {-# LANGUAGE GADTs, PatternGuards #-}
> |
> | data Bar a where
> | Listy :: Bar [Int]
> |
> | {-
> | foo :: a -> Bar a -> Int
> | foo [0] Listy = 1
> |
> | gadtTest.hs:8:5:
> | Couldn't match expected type `a' with actual type `[a0]'
> | `a' is a rigid type variable bound by
> | the type signature for: foo :: a -> Bar a -> Int
> | at /home/ggreif/gadtTest.hs:7:8
> | Relevant bindings include
> | foo :: a -> Bar a -> Int (bound at /home/ggreif/gadtTest.hs:8:1)
> | In the pattern: [0]
> | In an equation for `foo': foo [0] Listy = 1 -}
> |
> | foo' :: Bar a -> a -> Int
> | foo' Listy [a] = a
> |
> | foo'' :: a -> Bar a -> Int
> | foo'' l Listy | [a] <- l = a
> | -----------------------------------------------------------------
> |
> | the "wrong" order of pattern matches (i.e. foo) causes an error, the
> | flipped order works (i.e. foo') and pattern guards remedy the situation
> | (e.g. foo'').
> |
> | Since the type signatures are isomorphic this is a bit disturbing. Why
> | is it like this?
> | My guess is that patterns are matched left-to-right and refinements
> | become available "too late". Or is the reason buried in the OutsideIn
> | algorithm (and function arrow associativity: a -> (Bar a -> Int)) ?
> |
> | Would it be a big deal to forward-propagate type information in from
> | GADT pattern matches?
> |
> | Thanks and cheers,
> |
> | Gabor
> |
> | On 3/2/15, Simon Peyton Jones <simonpj at microsoft.com> wrote:
> | > GHC developers
> | > You may be interested in this paper, submitted to ICFP GADTs meet
> | > their match: pattern-matching warnings that account for GADTs,
> | guards,
> | > and
> | > laziness<http://research.microsoft.com/%7Esimonpj/papers/pattern-
> | match
> | > ing>, with Georgios Karachalias, Tom Schrijvers, and Dimitrios
> | > Vytiniotis.
> | > It describes a GADT-aware algorithm for detecting missing and
> | > redundant patterns.
> | > The implementation is not yet up to production quality, but it will
> | be!
> | > If you feel able to give us any feedback about the paper itself, that
> | > would be incredibly useful. Thanks Simon
> | >
> | >
> | _______________________________________________
> | ghc-devs mailing list
> | ghc-devs at haskell.org
> | http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
>
More information about the ghc-devs
mailing list