caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Christopher Zimmermann <madroach@gmerlin.de>
To: caml-list@inria.fr
Subject: [Caml-list] Polymorphic variant subtyping riddle
Date: Tue, 3 Dec 2019 22:50:48 +0100	[thread overview]
Message-ID: <20191203215048.GA80518@mortimer.gmerlin.de> (raw)


[-- Attachment #1.1: Type: text/plain, Size: 2989 bytes --]

Hi,

I've just encountered a type failure which I can easily solve by adding 
a subtyping constraint, but fail to see why it is necesarry.

The following example code types just fine:

```
type safe = [ `A | `B ]

type basic = [ `A ]

let basic :basic = `A

let of_safe :safe -> char = function
   | `A -> 'a'
   | `B -> 'b'

let relaxed =
   (of_safe
    : safe -> char
    :> [< safe ] -> char)

let x = relaxed basic
```

note that there is no subtyping constraint used in the application of 
``relaxed`` function to ``basic``.

But an analogous piece of code with more complex polymorphic variant 
types fails to type:

```
let relaxed =
   (conv
    : Yojson.Safe.t -> ('a, string) Result.t
    :> [< Yojson.Safe.t] -> ('a, string) Result.t)
in
relaxed (Basic.from_string s)
```

this is the explanation of the compiler:

```
477 |         (Basic.from_string s)
               ^^^^^^^^^^^^^^^^^^^^^
Error: This expression has type
          Basic.t =
            [ `Assoc of (string * Basic.t) list
            | `Bool of bool
            | `Float of float
            | `Int of int
            | `List of Basic.t list
            | `Null
            | `String of string ]
        but an expression was expected of type
          [< Safe.t > `Null `String ] =
            [< `Assoc of (string * Safe.t) list
             | `Bool of bool
             | `Float of float
             | `Int of int
             | `List of Safe.t list
             | `Null
             | `String of string
             > `Null `String ]
        Type
          Basic.t =
            [ `Assoc of (string * Basic.t) list
            | `Bool of bool
            | `Float of float
            | `Int of int
            | `List of Basic.t list
            | `Null
            | `String of string ]
        is not compatible with type
          Safe.t =
            [ `Assoc of (string * Safe.t) list
            | `Bool of bool
            | `Float of float
            | `Int of int
            | `Intlit of string
            | `List of Safe.t list
            | `Null
            | `String of string
            | `Tuple of Safe.t list
            | `Variant of string * Safe.t option ] 
        The first variant type does not allow tag(s) `Intlit, `Tuple, `Variant
```

The typechecker can be persuaded to let this pass by adding a subtyping 
constraint:
```
let relaxed =
   (conv
    : Yojson.Safe.t -> ('a, string) Result.t
    :> [< Yojson.Safe.t] -> ('a, string) Result.t)
in
relaxed (Basic.from_string s : Yojson.Basic.t :> Yojson.Safe.t)
```
will type just fine.


Now I'm confused why the subtyping constraint is only needed for the 
more complex polymorphic variant type and can be avoided in the 
simplified experiment.

Any insight is appreciated


Christopher


-- 
http://gmerlin.de
OpenPGP: http://gmerlin.de/christopher.pub
CB07 DA40 B0B6 571D 35E2  0DEF 87E2 92A7 13E5 DEE1

[-- Attachment #1.2: Type: text/html, Size: 4313 bytes --]

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

             reply	other threads:[~2019-12-05 10:47 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-12-03 21:50 Christopher Zimmermann [this message]
2019-12-05 11:04 ` Florian Angeletti

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=20191203215048.GA80518@mortimer.gmerlin.de \
    --to=madroach@gmerlin.de \
    --cc=caml-list@inria.fr \
    /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).