caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: David Allsopp <dra-news@metastack.com>
To: Leo White <lpw25@cam.ac.uk>
Cc: OCaml List <caml-list@inria.fr>
Subject: RE: [Caml-list] Match error with abstract types in modules
Date: Tue, 24 Feb 2015 18:26:41 +0000	[thread overview]
Message-ID: <E51C5B015DBD1348A1D85763337FB6D9E994424B@Remus.metastack.local> (raw)
In-Reply-To: <87wq372noc.fsf@study.localdomain>

Leo White wrote:
> > Please could someone remind me what it is about types in modules which
> > means that
> >
> >   module Foo = struct
> >     type 'a foo
> >   end
> >
> >   type _ t = A : int Foo.foo t
> >            | B : float Foo.foo t
> >
> >   let foo A = ()
> >
> > is non-exhaustive pattern matching, but:
> >
> >   type 'a bar
> >
> >   type _ u = C : int bar u
> >            | D : float bar u
> >
> >   let bar C = ()
> >
> > is exhaustive? Or is it actually a bug (given that foo B is a type
> error)?
> >
> 
> If Foo is replaced with:
> 
>     module Foo : sig
>       type 'a foo
>     end = struct
>       type 'a foo = unit
>     end
> 
> so that `int foo` is equal to `float foo`, then your match isn't really
> exhaustive.

How so? What's (very) confusing to me is that it seems to permit nonsensical matches without warning. In both the unconstrained and constrained versions of Foo, the resulting type of the function [foo] is [int Foo.foo t -> unit] so [foo B] is always rejected. But you get no warning about an unusable match case with:

let foo = function A -> () | B -> ()

although 

let foo = function A | B -> ()

unsurprisingly does not type.

> In the second version, the compiler cheats. Since `bar` is definied in the
> same module, it knows that the abstract `bar` type it can see is actually
> the definition, not just an abstraction of a type defined elsewhere, so it
> knows that `int bar` cannot equal `float bar`.
> 
> Personally, I dislike this behaviour and would prefer both cases to give
> an error.

What's to dislike? It's rather useful - the constructors of a GADT are partionable by type. What caught me out was that two constructors with distinct types (in my actual use with different instantiations of 'a BatSet.t) were being regarded as equal in terms of pattern matching. I'd be quite happy if a type annotation were necessary to make it explicit that I meant to do it:

let foo (key : int Foo.foo t) =
  match key with A -> ()

Especially with that explicit type, I find it very odd to get a warning about a constructor whose type is not permitted in this context and so cannot be matched.

Ta for the explanation behind the difference in behaviour, regardless!


David

  reply	other threads:[~2015-02-24 18:26 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-02-24 17:25 David Allsopp
2015-02-24 18:02 ` Leo White
2015-02-24 18:26   ` David Allsopp [this message]
2015-02-24 19:11     ` Leo White
2015-02-25  8:41       ` David Allsopp
2015-02-24 19:52     ` Jeremy Yallop
2015-02-24 20:03       ` Ben Millwood
2015-02-24 21:11         ` Leo White
2015-02-25  8:41           ` David Allsopp
2015-02-25  9:48             ` Gabriel Scherer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=E51C5B015DBD1348A1D85763337FB6D9E994424B@Remus.metastack.local \
    --to=dra-news@metastack.com \
    --cc=caml-list@inria.fr \
    --cc=lpw25@cam.ac.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).